如果结构体具有参数实现接口的方法,则该结构体不实现接口

Abd*_*aja 3 struct interface go

我有一个包,其中有两个接口

package main

type A interface {
    Close()
}

type B interface {
    Connect() (A, error)
}
Run Code Online (Sandbox Code Playgroud)

我还有两个实现这些接口的结构

type C struct {
}

func (c *C) Close() {

}

type D struct {
}

func (d *D) Connect() (*C, error) {
    c := new(C)
    return c, nil
}
Run Code Online (Sandbox Code Playgroud)

接下来我有一个函数,它作为参数需要一个实现接口 B 的对象

func test(b B) {
}
Run Code Online (Sandbox Code Playgroud)

最后,在 main() 函数中我创建了 D 结构对象并想要调用 test() 函数

func main() {
    d := new(D)
    test(d)
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试构建该包,则会出现错误。

无法在测试参数中使用 d(类型 *D)作为类型 B:*D 未实现 B(Connect 方法的类型错误)有 Connect()(*C,错误)想要 Connect()(A,错误)

这是我的代码的简单示例,我使用外部包并想要模拟结构进行测试。使用接口而不是类型有什么解决方案吗?

Him*_*shu 5

为了实现该接口,需要关注一个问题:

Go 类型通过实现接口的方法来满足接口,仅此而已。此属性允许定义和使用接口,而无需修改现有代码。它支持一种结构类型,可以促进关注点分离并提高代码重用性,并且可以更轻松地构建随着代码开发而出现的模式。

您收到的错误是因为D您用作测试函数参数的结构未实现该接口。Connect其背后的原因是您使用的接收器功能D不同。由于它有不同的返回类型:

func (d *D) Connect() (*C, error) { // the struct D does not implement the interface B because of wrong function definition to interface B function
    c := new(C)
    return c, nil
}
Run Code Online (Sandbox Code Playgroud)

而如果你想实现接口,B函数定义及其返回类型应该与接口中的函数匹配,B

type B interface {
    Connect() (A, error)
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您想实现该接口,您使用的 Connect 方法应该与接口 B 的 Connect 方法相匹配

package main

type A interface {
    Close()
}
type B interface {
    Connect() (A, error)
}

type C struct {
}

func (c *C) Close() {

}

type D struct {
}

func (d *D) Connect() (A, error) {
    c := new(C)
    return c, nil
}

func test(b B) {}

func main() {
    d := new(D)
    test(d)
}
Run Code Online (Sandbox Code Playgroud)

检查Go Playground

考虑这个简单的接口来表示一个可以将自身与另一个值进行比较的对象:

type Equaler interface {
    Equal(Equaler) bool
}
Run Code Online (Sandbox Code Playgroud)

这个类型,T:

type T int
func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler
Run Code Online (Sandbox Code Playgroud)

T.Equal 的参数类型是 T,而不是字面上所需的 Equaler 类型。

在 Go 中,类型系统不提倡 Equal 参数;这是程序员的责任,如类型 T2 所示,它确实实现了 Equaler:

type T2 int
func (t T2) Equal(u Equaler) bool { return t == u.(T2) }  // satisfies Equaler
Run Code Online (Sandbox Code Playgroud)