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

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

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

Go
婷婷同学_ 2022-07-11 14:56:06
在 Go2 泛型中,截至目前的草案,我可以使用接口在泛型类型上指定类型约束。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 intfunc (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带有合同的原始草案将使这成为可能,但新草案却没有。它也可以通过以下方式完成,但这会让您一遍又一遍地重复相同的约束,制动 DRY(并且 DRY 代码是泛型的目的)。如果所需的接口有多个方法,它也会使代码更加笨拙。func IsLess[T interface { Less(T) bool }](lhs, rhs, T) bool {    return lhs.Less(rhs)}有没有办法在新草案中使用预定义的接口来做到这一点?
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

定义接口类型Lesser和功能Isless如下:


type Lesser[T any] interface {

    Less(T) bool

}


func IsLess[T Lesser[T]](lhs, rhs T) bool {

    return lhs.Less(rhs)

}

然后,以下代码可以顺利编译:


type Apple int


func (lhs Apple) Less(rhs Apple) bool {

    return lhs < rhs

}


type Orange int


func (lhs Orange) Less(rhs Orange) bool {

    return lhs < rhs

}


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 satisfy 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

}

(游乐场)


约束T Lesser[T]可以读作


任何T有Less(T) bool方法的类型。


我的两种自定义类型,


Apple用它的Less(Apple) bool方法,和

Orange用它的Less(Orange) bool方法,

满足这个要求。


作为信息,Java 泛型允许通过所谓的递归类型绑定来实现类似的技巧。有关此主题的更多信息,请参阅 Josh Bloch 的Effective Java第 3 版中的第 30 项(尤其是 p137-8)。


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号