我有一个包含两个接口的程序包
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(* D型)作为B型: * D没有实现B(Connect方法的类型错误) 有Connect()(* C,错误) 想要Connect()(A,错误)
这是我的代码的简单示例,其中我使用外部包并希望模拟结构进行测试。使用接口代替类型有什么解决方案吗?
答案 0 :(得分:2)
您的Connect
方法返回的类型应该是A
而不是*C
。
您定义Connect
方法的方式是它应该返回一个接口,而不是特定的类型。在实现*C
接口的情况下,您仍然可以返回A
。
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)
println("successfully created new C:", c)
return c, nil
}
func test(b B) {
b.Connect()
}
func main() {
d := new(D)
test(d)
}
输出
成功创建了新的C:0xe28f0
亲自尝试here
答案 1 :(得分:1)
要实现该接口,需要关注的是:
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