我是 Go 新手,对接口在实现时如何工作感到有点困惑,尤其是 wrt。有参数的函数。假设我有一个带有函数
foo
的接口,它接受一个接口:
type I interface {
foo(x interface{})
}
还有类型
A
和 B
如下:
type A struct {
// stuff
}
type B struct {
// stuff
}
(a *A) foo(b B) {
// do something
}
既然在这个例子中,
A
有方法foo
,那么即使使用I
的规范作为参数而不是通用接口,它是否被认为已经实现了B
?我对函数的返回类型也有同样的问题。
如果没有,如何设计一个接口来允许更通用的参数/返回类型以及实现它的结构来指定类型?
A有方法
,是否认为已经实现了foo
I
没有。
接口
I
由一个方法 foo
组成,该方法接受 interface{}
参数。 这并不意味着它接受任何类型的单个参数。 这意味着它接受一个使用空方法集实现特定接口的参数。
对于此类参数采用 any
类型可能会帮助你理解区别(从 go 1.18 开始支持):
type I interface {
foo(x any)
}
为了满足此接口,类型必须实现一个方法
foo
接受
any
参数;仅使用单个参数实现 foo
方法是不够的,其中该参数的类型无关。您似乎正在寻找一个generic接口(泛型也在go 1.18中引入):
type I[T any] interface {
foo(T)
}
通用接口
T
上的类型参数
I
具有 any
约束,这意味着可以提供任何类型。如果类型A
实现了接受
foo
类型参数的B
方法,那么这将被视为实现了接口I[B]
:type I[T any] interface {
foo(B)
}
type A struct{}
type B struct{}
func (A) foo(B) { log.Println("it works") }
func main() {
var a any = A{}
c := a.(I[B])
c.foo(B{})
}
游乐场a
使用
A
类型的值进行初始化,但 a
本身是 any
类型,因此不能直接用于调用 foo()
方法。c
通过将
a
强制到接口 I[B]
来初始化,从而允许调用 foo(B)
方法。