gpt4 book ai didi

go - 使用定义的类型而不是类型文字的递归类型约束?

转载 作者:行者123 更新时间:2023-12-03 08:33:51 25 4
gpt4 key购买 nike

在 Go2 泛型中,从当前草案开始,我可以使用接口(interface)指定泛型类型的类型约束。

import "fmt"

type Stringer interface {
String() string
}

func Print[T Stringer](value T) {
fmt.Println(value.String())
}

这样,我可以指定该类型必须实现一个方法。但是,我没有看到任何方法可以强制执行方法,该方法本身具有泛型类型的参数。

type Lesser interface {
Less(rhs Lesser) bool
}

type Int int

func (lhs Int) Less(rhs Int) bool {
return lhs < rhs
}

func IsLess[T Lesser](lhs, rhs T) bool {
return lhs.Less(rhs)
}

func main() {
IsLess[Int](Int(10), Int(20))
}

退出

Int does not satisfy Lesser: wrong method signature
got func (Int).Less(rhs Int) bool
want func (Lesser).Less(rhs Lesser) bool

带有契约(Contract)的原始草案将使这成为可能,但新草案则不然。

也可以通过以下方式完成,但这会让您一遍又一遍地重复相同的约束,从而阻止 DRY(DRY 代码是泛型的目的)。如果所需的接口(interface)有多个方法,它也会使代码变得更加笨拙。

func IsLess[T interface { Less(T) bool }](lhs, rhs, T) bool {
return lhs.Less(rhs)
}

有没有办法通过新草案中的预定义界面来做到这一点?

最佳答案

定义接口(interface)类型Lesser和函数Isless如下:

type Lesser[T any] interface {
Less(T) bool
}

func IsLess[T Lesser[T]](x, y T) bool {
return x.Less(y)
}

然后,以下代码可以正常编译:

type Apple int

func (a Apple) Less(other Apple) bool {
return a < other
}

type Orange int

func (o Orange) Less(other Orange) bool {
return o < other
}

func main() {
fmt.Println(IsLess(Apple(10), Apple(20))) // true
fmt.Println(IsLess(Orange(30), Orange(15))) // false

// fmt.Println(IsLess(10, 30))
// compilation error: int does not implement Lesser[T] (missing method Less)

// fmt.Println(IsLess(Apple(20), Orange(30)))
// compilation error: type Orange of Orange(30) does not match inferred type Apple for T
}

( Playground )


约束T Lesser[T]可以读作

any type T that has a Less(T) bool method.

我的两种自定义类型,

  • Apple 及其 Less(Apple) bool 方法,以及
  • Orange 及其 Less(Orange) bool 方法,

满足此要求。

仅供引用,Java 泛型允许通过所谓的 recursive type bound 实现类似的技巧。 。有关此主题的更多信息,请参阅 Josh Bloch 的 Effective Java,第 3 版中的第 30 项(尤其是第 137-8 页)。


全面披露:当我遇到Vasko Zdravevski's solution时,我想起了这个悬而未决的问题。至a similar problemGophers Slack .

关于go - 使用定义的类型而不是类型文字的递归类型约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64468241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com