首页 > 解决方案 > 如果结构有参数实现接口的方法,则结构不实现接口

问题描述

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

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() (*C, error) {
    c := new(C)
    return c, nil
}

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

func test(b B) {
}

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

func main() {
    d := new(D)
    test(d)
}

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

不能在测试的参数中使用 d (type *D) 作为 type B: *D does not implement B (error type for Connect method) have Connect() (*C, error) want Connect() (A, error)

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

标签: gostructinterface

解决方案


为了实现接口,需要关注的是:

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
}

而如果要实现接口B,则函数定义及其返回类型应与接口中的函数相匹配B,即

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

所以如果你想实现接口,你使用的 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)
}

检查去游乐场

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

type Equaler interface {
    Equal(Equaler) bool
}

这种类型,T:

type T int
func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler

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

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

type T2 int
func (t T2) Equal(u Equaler) bool { return t == u.(T2) }  // satisfies Equaler

推荐阅读