go - 如果结构具有参数实现接口(interface)的方法,则结构不实现接口(interface)

标签 go struct interface

我有一个包,其中有两个接口(interface)

package main

type A interface {
    Close()
}

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

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

type C struct {
}

func (c *C) Close() {

}

type D struct {
}

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

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

func test(b B) {
}

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

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

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

cannot use d (type *D) as type B in argument to test: *D does not implement B (wrong type for Connect method) have Connect() (*C, error) want Connect() (A, error)

这是我的代码的简单示例,我在其中使用外部包并希望为测试模拟结构。使用接口(interface)而不是类型是否有任何解决方案?

最佳答案

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

A Go type satisfies an interface by implementing the methods of that interface, nothing more. This property allows interfaces to be defined and used without having to modify existing code. It enables a kind of structural typing that promotes separation of concerns and improves code re-use, and makes it easier to build on patterns that emerge as the code develops.

你得到的错误是因为你用作测试函数参数的结构 D 没有实现接口(interface)。这背后的原因是您与接收器 D 一起使用的函数 Connect 是不同的。因为它有不同的返回类型:

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
}

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

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

所以如果你想实现接口(interface)你使用的Connect方法应该匹配接口(interface)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)
}

查看Go Playground

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

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

关于go - 如果结构具有参数实现接口(interface)的方法,则结构不实现接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51945006/

相关文章:

java - 接口(interface)内 transient

Golang time.Ticker,如何从偶数时间戳开始

go - 如何在go lang中接收多帧二进制数据

go - 预提交打印 'golint: command not found'

戈朗 : cgo extern is not working

c - 结构中的初始化错误

C++ 错误此声明没有存储类或类型说明符

c - Swift:将未初始化的 C 结构传递给导入的 C 函数

android - 类和 Activity 通过接口(interface)进行通信

c# - WCF 服务客户端