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

Golang:如何嵌入具有不同类型参数的接口?

Golang:如何嵌入具有不同类型参数的接口?

Go
蛊毒传说 2023-02-14 17:58:06
代码给我错误:DB redeclared。有没有惯用的方法来解决它?或者任何解决方法?爱type a struct {    DB[int64]    DB[string]}type b interface {    DB[int64]    DB[string]}type DB[T any] interface {    GetList(query string) ([]T, error)}
查看完整描述

1 回答

?
梦里花落0921

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

你不能嵌入相同的接口,即使有不同的类型参数。不管它是如何实例化的,您都试图将b两个具有相同名称GetList 和不同签名的方法提升到接口中——由DB.


嵌入到结构中的情况类似,尽管在技术上并不相同。在结构体中,嵌入字段的名称是类型的名称—— DB,一个结构体不能有两个同名的非空白字段。


关于如何解决这个问题,这取决于你想要完成什么。


如果您想传达“使用任一类型参数a实现DB”,您可以嵌入DB[T]并使其成为a通用的,并限制a其类型参数:


type a[T int64 | string] struct {

    DB[T]

}


// illustrative implementation of the DB[T] interface

// if you embed DB[T] you likely won't use `a` itself as receiver

func (r *a[T]) GetList(query string) ([]T, error) {

    // also generic method

}


这没关系,因为DB的类型参数被限制为any,并且a的类型参数更具限制性。这允许您在其他泛型方法中使用a,或在实例化时选择特定类型,但 的实现GetList也必须参数化。


否则,如果你需要a有返回or的分离方法,你必须给它不同的名字。int64string


最后,您可以将 的实例嵌入DB到两个具有不同名称的接口中,然后将它们嵌入到ainstead 中。


type a struct {

    DBStr

    DBInt

}


type DBStr interface {

    DB[string]

}


type DBInt interface {

    DB[int64]

}

这样虽然顶级选择器不可用,因为方法名称仍然相同。该程序可以编译,但您必须明确选择要在哪个字段上调用该方法:


myA := a{ /* init the two fields */ }


res, err = myA.DBStr.GetList(query)

// res is type []string

// or

res, err = myA.DBInt.GetList(query)

// res is type []int64


查看完整回答
反对 回复 2023-02-14
  • 1 回答
  • 0 关注
  • 95 浏览
慕课专栏
更多

添加回答

举报

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