我有以下代码:
package main
type MyInterface interface {
Test()
}
type MyType struct {
}
func (m MyType) Test(){}
func AcceptInterface(i *MyInterface){
}
func main() {
object := &MyType{}
AcceptInterface(object)
}
Run Code Online (Sandbox Code Playgroud)
我期待这个工作,因为MyType实现了MyInterface,但我得到:
不能在AcceptInterface的参数中使用对象(类型*MyType)作为类型*MyInterface:*MyInterface是指向接口的指针,而不是接口
我尝试做类型断言:对象.(MyInterface),但这也不起作用.
我怎么能做到这一点?
正如错误所说,
不能在AcceptInterface的参数中使用对象(类型*MyType)作为类型*MyInterface:*MyInterface是指向接口的指针,而不是接口
这意味着它期望一个interface值,而不是一个指针.
如果您更改代码中的值指针(通过删除&和*),程序将运行没有错误:
package main
type MyInterface interface {
Test()
}
type MyType struct {
}
func (m MyType) Test(){}
func AcceptInterface(i MyInterface){
}
func main() {
object := MyType{}
AcceptInterface(object)
}
Run Code Online (Sandbox Code Playgroud)
如果您仍想使用指针作为参数,则需要注意Go语言的两个重要部分
从围棋规格上有什么exacly是适合一个实例变量:
接口类型的变量可以使用方法集存储任何类型的值,该方法集是接口的任何超集.
从Go Spec中可以自动解除引用的指针:
与选择器一样,使用指针对带有值接收器的非接口方法的引用将自动取消引用该指针:
pt.Mv等同于(*pt).Mv[和]方法调用,使用指针接收器的非接口方法的引用可寻址值将自动获取该值的地址:t.Mp相当于(&t).Mp.
这两点很重要,因为结合使用时他们会解释变量的指针仍然可以适合实例.这是因为Go编译器会自动取消引用指针的方法集(因为它引用的变量可以适合实例,指针也可以)!
在操作中,这意味着为了查看指针是否适合实例,您必须将实例声明为值,将指针声明为指针.
如果您运行此代码:
package main
type MyInterface interface {
Test()
}
type MyType struct {
}
func (m MyType) Test() {}
func AcceptInterface(i MyInterface) {
}
func main() {
object := &MyType{}
AcceptInterface(object)
}
Run Code Online (Sandbox Code Playgroud)
你会发现没有错误!请注意有是一个&在object声明,但没有*在i声明中?