烟台网站建设服务,新钥匙网站建设,最低的成本做网站,百度账户推广登陆golang 函数式编程库samber/mo使用#xff1a; Either
如果您不了解samber/mo库#xff0c; 请先阅读第一篇 Option
结构定义
有时候我们不确定值的类型#xff0c; 一个值可能是int#xff0c; 也可能是string#xff0c; 这时候我们可以使用Either类型。 Either类型是…golang 函数式编程库samber/mo使用 Either
如果您不了解samber/mo库 请先阅读第一篇 Option
结构定义
有时候我们不确定值的类型 一个值可能是int 也可能是string 这时候我们可以使用Either类型。 Either类型是一种表示两种可能值的类型 和python中的 Optional类似。 结构定义如下
type Either[L any, R any] struct {isLeft boolleft Lright 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 mainimport (errorsfmt
)var (ErrRedisNotFound errors.New(redis not found)ErrDBNotFound errors.New(db not found)
)func readFromRedis() (string, error) {// lets simulate a failed operationreturn , ErrRedisNotFound
}func readFromDB() (string, error) {// lets simulate a successful operationreturn 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 mainimport (errorsfmtgithub.com/samber/mo
)var (ErrRedisNotFound errors.New(redis not found)ErrDBNotFound errors.New(db not found)
)func readFromRedis() mo.Either[string, error] {// lets simulate a failed operationreturn mo.Right[string, error](ErrRedisNotFound)
}func readFromDB() mo.Either[string, error] {// lets simulate a success operationreturn 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)},)},)
}
代码虽然更长了但是逻辑结构很清晰