我有以下代码:
package main
type MyInterface interface {
Test()
}
type MyType struct {
}
func (m MyType) Test(){}
func AcceptInterface(i *MyInterface){
}
func main() {
object := &MyType{}
AcceptInterface(object)
}
我期待这个工作,因为MyType实现了MyInterface,但我得到了:
不能在对象中使用对象(类型* MyType)作为类型* MyInterface AcceptInterface:* MyInterface是指向接口的指针,而不是接口
我尝试做类型断言:object。(MyInterface),但这也不起作用。
我该如何做到这一点?
答案 0 :(得分:8)
正如错误所说,
不能在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)
}
如果您仍想使用指针作为参数,则需要注意Go语言的两个重要部分
来自Go Spec的 exacly 是一个适合实例的变量:
接口类型的变量可以存储任何类型的值,其方法集是接口的任何超集。
从Go Spec开始自动取消引用的指针:
与选择器一样,使用指针对带有值接收器的非接口方法的引用将自动取消引用该指针:
pt.Mv
等同于(*pt).Mv
[和],与方法调用一样,a使用可寻址值的指针接收器对非接口方法的引用将自动获取该值的地址:t.Mp
等同于(&t).Mp.
这两点很重要,因为结合使用时他们会解释指向变量的指针仍然可以适合实例。这是因为指针的method set被Go编译器自动解除引用(因为它引用的变量可以适合实例,指针也可以)!
在操作中,这意味着为了查看指针是否适合实例,您必须将实例声明为值,将指针声明为指针。
如果您运行此代码:
package main
type MyInterface interface {
Test()
}
type MyType struct {
}
func (m MyType) Test() {}
func AcceptInterface(i MyInterface) {
}
func main() {
object := &MyType{}
AcceptInterface(object)
}
你会发现没有错误!请注意&
声明中的是 object
,*
声明中的否i
是什么?< / p>
答案 1 :(得分:0)
如果要将指针传递给interface:
,请使用显式输入func main() {
var object MyInterface = MyType{}
AcceptInterface(&object)
}
我不建议使用指针接口,因为您需要编写像(*i).Test()
这样的代码来调用接口指针方法。编译器对结构指针进行自动解除引用,而对于接口指针则不然。
答案 2 :(得分:-1)
type MyInterface interface {
Test()
}
type MyType struct {
}
func (m MyType) Test(){}
注意:这意味着MyType
实现了接口MyInterface
,而不是MyType*
。
您可以使用:
func (m *MyType) Test(){} //Notice here
func AcceptInterface(i *MyInterface){
}
func main() {
object := &MyType{}
AcceptInterface(object)
}