Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?
Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?
已经被 OOP 虐得死去活来,看了几天函数编程思想,仿佛见到光明。
Go 已经很爽了,如果再加入函数编程思想就更爽了。目前有一些库实现了 monad 的原型,但在实际使用中遇到一些问题。由于 Go 没有 Generic,所以只能由 interface 去代替,这样导致编译阶段无法判断调用链中的参数类型是否匹配。
type Maybe struct {
Val interface{}
err error
}
即上一个函数输出的 Maybe.Val ,不一定匹配下一个函数的入参。 既然编译时无法发现错误,只能运行时发现了,我目前做法是写一个 HappyPath 的单元测试,跑过整个调用链。但我本来就是想用 monad 把大块的逻辑拆开各自做单元测试,现在又合回来了。
各位有没有经验分享一下?
更多关于Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Scala 欢迎你(逃
更多关于Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
monad 是一种静态类型的机制
当你有动态机制时,那就没必要用这个。如果不是设计类型系统时就考虑到,那模拟出来是没意义的
用 reflect 包动态操作就行了,那些静态类型的概念全都可以略过,反正你不需要也做不到编译期的类型安全
还是缺泛型啊
没看懂,那你 Val 类型,改成某一个接口,而不是单纯的 interface{},不就行了吗
做不了,Go 缺乏必要的静态类型分析。就算做出个类似的,各种依赖运行时也完全是积累。
*鸡肋
做好了也只是玩具吧,各种类型反射转换,性能渣渣了
在Go语言没有原生支持Generic(泛型)之前,使用monad(单子)的概念确实会稍显复杂,因为monads通常依赖于泛型来提供类型安全和复用性。不过,通过一些设计模式和接口技巧,我们仍然可以在Go中模拟monads的行为。
首先,要明确的是,monads是一种在函数式编程中用于处理计算序列、错误处理、状态管理等的抽象结构。在Go中,我们可以利用接口来定义monads的行为,并通过实现这些接口来创建具体的monad类型。
例如,为了处理错误,我们可以定义一个ErrorMonad
接口,该接口包含一个返回可能错误结果的方法。然后,为不同的错误处理场景实现这个接口。
在没有泛型的情况下,我们需要为每种可能的类型实现这个接口。这会导致代码冗余,但它是模拟monads的一种可行方法。
另外,我们可以使用空接口interface{}
来模拟泛型的行为,但这会牺牲类型安全,并需要在运行时进行类型断言。
为了简化代码和提高可读性,通常会结合使用结构体和类型断言来处理不同类型的值。
随着Go 1.18引入了泛型,现在可以使用泛型来定义monads,从而大大简化了代码并提高了类型安全性。如果你正在使用Go 1.18或更高版本,建议利用泛型来定义和实现monads。
总之,在没有泛型的情况下,虽然可以使用monads,但会牺牲一些类型安全和代码复用性。通过接口和空接口的使用,可以模拟出类似的行为。