golang结构不实现接口?



我是围棋的初学者,所以请耐心等待。我有一个定义如下的接口:

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接口,然后用于模拟和单元测试。 但是,这会导致创建新存储库时出现问题:

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结构来说应该足够了,因为它具有相同的签名。我不确定我在这里做错了什么。

谢谢!。

方法的错误类型 放置 (have func(item interface{})

*github.com/guregu/dynamo.Put, want func(item interface{}) interface{Run() error})

您的函数返回一个*Put。 接口需要interface{Run() error}*Put可能满足此接口,但它们仍然是不同的类型。返回满足该接口的类型的函数签名不能与返回该接口的函数签名互换。

因此,首先为您的接口命名。 我们在 2 个地方引用它,您应该避免匿名接口(和结构)定义,因为它们没有固有的好处,并且使您的代码更冗长、更少 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.Table
func (table *dynamoTable) Put(item interface{}) Runner {
return (*dynamo.Table)(table).Put(item)
}

dynamo.Table仍然可以返回*Put,因为*Put实现了Runner。 返回值将Runner,基础类型将*Put。 然后接口将得到满足,并且该错误将被修复。

https://go.dev/play/p/y9DKgwWbXOO 说明了此重新键入和覆盖过程的工作原理。

最新更新