我有一个包,其中有两个接口(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)
}
考虑这个简单的接口(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/