golang 结构没有实现接口?

我是 go 的初学者,所以请多多包涵。我有一个定义如下的接口:


type DynamoTable interface {

    Put(item interface{}) interface{ Run() error }

}

我也有这样的Repo结构:


type TenantConfigRepo struct {

    table DynamoTable

}

我有一个结构dynamo.Table,它的Put函数定义如下:


func (table dynamo.Table) Put(item interface{}) *Put

该Put结构具有Run如下功能:


func (p *Put) Run() error

我想要做的是拥有一个通用DynamoTable接口,然后将其用于模拟和单元测试。然而,这会导致创建新 Repo 时出现问题:


func newDynamoDBConfigRepo() *TenantConfigRepo {

    sess := session.Must(session.NewSession())

    db := dynamo.New(sess)

    table := db.Table(tableName) //=> this returns a type dynamo.Table

    return &TenantConfigRepo{

        table: table,

    }

}

然而,这会引发这样的错误


cannot use table (variable of type dynamo.Table) as DynamoTable value in struct literal: wrong type for method Put (have func(item interface{}) *github.com/guregu/dynamo.Put, want func(item interface{}) interface{Run() error})


这对我来说很奇怪,因为据我所知,具有相同签名的接口Run() error对于结构来说应该足够了。Put我不确定我在这里做错了什么。


qq_遁去的一_1
浏览 86回答 1
1回答

万千封印

方法 Put 的类型错误(有 func(item interface{}) *github.com/guregu/dynamo.Put,想要 func(item interface{}) interface{Run() error})你的函数返回一个*Put. 该接口需要一个interface{Run() error}. A*Put可能满足这个接口,但它们仍然是不同的类型。 返回满足该接口的类型的函数签名不能与返回该接口的函数签名互换。因此,首先为您的界面命名。我们在两个地方提到它,你应该避免匿名接口(和结构)定义,因为它们没有内在的好处,会让你的代码更冗长,更少 DRY。type Runner interface{   Run() error}现在更新 DynamoTable 以使用该接口type DynamoTable interface {    Put(item interface{}) Runner}你说dynamo.Table的是你无法控制的。但是您可以创建一个等于的新类型dynamo.Table,然后覆盖该put方法。在重写的方法中,我们转换dynamoTable回dynamo.Table,调用原来的dynamo.Table.Put,然后返回结果。type dynamoTable dynamo.Tablefunc (table *dynamoTable) Put(item interface{}) Runner {  return (*dynamo.Table)(table).Put(item)}dynamo.Table仍然可以返回一个*Put因为*Putimplements Runner。返回值将为Runner,基础类型将为*Put。然后接口将得到满足,错误将被修复。https://go.dev/play/p/y9DKgwWbXOO说明了这个重新输入和覆盖过程是如何工作的。
打开App,查看更多内容
随时随地看视频慕课网APP