在各种编程语言(例如 Haskell)中,fmap 是将函数应用于数据结构同时保留其类型的宝贵工具。然而,由于其基于方法的泛型,在 Go 中实现 fmap 的直接等效项提出了独特的挑战。问题出现了:我们如何在不影响类型安全的情况下模拟 Go 中的 fmap 功能?
Go 泛型的局限性
不幸的是,Go 目前的泛型系统并不适合自己通过方法直接模拟 fmap。方法参数无法引入新的类型参数,导致问题中提到的类型不匹配错误。
替代方法
虽然使用类似的方法可能很诱人对于 Haskell 来说,以下考虑因素导致了更明智的选择:
fmap 作为顶级函数
在 Go 中模拟 fmap 的推荐方法是将其定义为任何类型之外的顶级函数。下面是一个示例:
package main import "fmt" type S[A any] struct { contents A } func Fmap[A, B any](sa S[A], f func(A) B) S[B] { return S[B]{contents: f(sa.contents)} } func main() { ss := S[string]{"foo"} f := func(s string) int { return len(s) } fmt.Println(Fmap(ss, f)) // {3} }
这种方法与 Go 的基于方法的泛型更好地保持一致,同时保持类型安全性和可读性。
结论
尽管将其他语言的概念直接翻译成 Go 可能很诱人,但考虑 Go 语言固有的局限性很重要。通过采用更惯用的基于 Go 的方法来模拟 fmap,我们可以在遵循 Go 的设计原则的同时实现所需的功能。
以上是我们如何在保持类型安全的同时模拟 Go 中的 fmap 功能?的详细内容。更多信息请关注PHP中文网其他相关文章!