为了账号安全,请及时绑定邮箱和手机立即绑定

Go:自己的 List 类型与自己的 Functor 类型不兼容

Go:自己的 List 类型与自己的 Functor 类型不兼容

Go
慕妹3146593 2023-01-03 11:26:20
为了更多地了解Go、泛型和函数式编程,我实现了一个List类型(摘自list.go):package funcprogtype Function[T any] func(T) Ttype List[T any] []Tfunc (l List[T]) Map(f Function[T]) List[T] {    var ys List[T]    for _, x := range l {        y := f(x)        ys = append(ys, y)    }    return ys}效果很好(main.go):package mainimport (    "fmt"    "funcprog")func main() {    numbers := funcprog.List[int]{0, 1, 2, 3}    twice := func(x int) int { return x * 2 }    fmt.Println(numbers.Map(twice))}$ go run main.go[0 2 4 6]我List的其实是一个Functor,所以我写了这个接口(functor.go):package funcprogtype Functor[T any] interface {    Map(Function[T]) Functor[T]}但是,如果我想将我List的用作Functor( main.go,已修改):import (    "fmt"    "funcprog")func demo[T int](f funcprog.Functor[T]) {    fmt.Println(f.Map(func(x T) T { return x * 2 }))}func main() {    numbers := funcprog.List[int]{0, 1, 2, 3}    demo[int](numbers)}我收到此错误:funcprog.List[int] does not implement funcprog.Functor[int] (wrong type for Map method)    have Map(f funcprog.Function[int]) funcprog.List[int]    want Map(funcprog.Function[int]) funcprog.Functor[int]我的不List[int]也是一个Functor[int],因为List[T]满足Functor[T]吗?
查看完整描述

2 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

当查看一个类型是否实现了一个接口时,go 不会尝试对该函数签名的元素进行“接口映射”,它只会比较确切的签名。


如果你想让你的List[T]类型实现你的Functor[T]接口,你应该改变Map()方法的签名:


func (l List[T]) Map(f Function[T]) Functor[T] {

    ...

}

额外提一点:这与泛型无关,而是与如何在接口上实现类型检查有关。


这是另一个例子(没有泛型):


type MyStr string


// MyStr implements fmt.Stringer

func (s MyStr) String() string {

    return string(s)

}


// but this method does not fulfill the Concatter interface below

func (s MyStr) Concat(x string) MyStr {

    return s + " " + MyStr(x)

}


type Concatter interface {

    Concat(s string) fmt.Stringer

}


var _ Concatter = MyStr("") // compilation error

https://go.dev/play/p/tKDGEXlYHyl


查看完整回答
反对 回复 2023-01-03
?
慕丝7291255

TA贡献1859条经验 获得超6个赞

函数签名中的类型必须完全匹配。所以你只需要改变List.Map方法的返回类型来返回一个Functor[T].

func (l List[T]) Map(f Function[T]) Functor[T]

现在可以编译了,因为List[T]确实用它自己的方法实现 ,并且实例化 和共享相同的具体类型。Functor[T]MapdemoList

固定游乐场:https ://go.dev/play/p/a4GeqXstjct

我的List[int]不也是Functor[int]吗,因为List[T]满足Functor[T]?

是的,但是 Go generics不支持任何形式的 type variance,因此List[T]在您的示例中返回方法签名不同于接口的方法签名。


查看完整回答
反对 回复 2023-01-03
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信