赞
踩
如果您不了解samber/mo库, 请先阅读第一篇 Option
有时候我们不确定值的类型, 一个值可能是int, 也可能是string, 这时候我们可以使用Either类型。 Either类型是一种表示两种可能值的类型, 和python中的 Optional类似。 结构定义如下:
type Either[L any, R any] struct {
isLeft bool
left L
right R
}
其中 isLeft表示值的类型, left和right分别表示两种可能的值。 如果isLeft为true, 则left有值, right为nil; 如果isLeft为false, 则right有值, left为nil。
主要有一下两个:
mo.Left()
函数定义为 func Left[L any, R any](value L) Either[L, R]
L, R分别表示两种可能的值的类型, value表示左值。 doc
mo.Right()
和Left类似 doc
Either类型最常见的用法是处理错误, 正好适用于go语言。 因为go语言没有提供 try...catch
语法, 优点是错误显式处理,可以避免忘记捕获异常, 缺点是代码不够优雅。
举个例子, 如果我们用go自带的error处理, 代码如下:
package main import ( "errors" "fmt" ) var ( ErrRedisNotFound = errors.New("redis not found") ErrDBNotFound = errors.New("db not found") ) func readFromRedis() (string, error) { // let's simulate a failed operation return "", ErrRedisNotFound } func readFromDB() (string, error) { // let's simulate a successful operation return "user:1:Samber", nil } func main() { data, err := readFromRedis() if err != nil { fmt.Println("redis not found, read from db") data, err = readFromDB() if err != nil { fmt.Println("db not found") } else { fmt.Println("data from db is:", data) } } else { fmt.Println("data from redis", data) } }
可以看到里面充满了if else, 代码中的逻辑结构表达得不够清晰。 使用Either处理错误的代码如下:
package main import ( "errors" "fmt" "github.com/samber/mo" ) var ( ErrRedisNotFound = errors.New("redis not found") ErrDBNotFound = errors.New("db not found") ) func readFromRedis() mo.Either[string, error] { // let's simulate a failed operation return mo.Right[string, error](ErrRedisNotFound) } func readFromDB() mo.Either[string, error] { // let's simulate a success operation return mo.Left[string, error]("user:1:Samber") } func main() { readFromRedis(). Match( func(data string) mo.Either[string, error] { fmt.Println("data from redis", data) return mo.Left[string, error](data) }, func(err error) mo.Either[string, error] { fmt.Println("redis not found, read from db") return readFromDB(). Match( func(data string) mo.Either[string, error] { fmt.Println("data from db is:", data) return mo.Left[string, error](data) }, func(err error) mo.Either[string, error] { fmt.Println("db not found") return mo.Right[string, error](err) }, ) }, ) }
代码虽然更长了,但是逻辑结构很清晰
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。