为接受接口的函数传递结构 [英] Pass struct for function that accepts a interface

查看:53
本文介绍了为接受接口的函数传递结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

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,但是我得到了:

I was expecting this to work, because MyType implements MyInterface, but I get:

不能将对象(类型* MyType)用作类型* MyInterface的参数AcceptInterface:* MyInterface是指向接口的指针,而不是接口

cannot use object (type *MyType) as type *MyInterface in argument to AcceptInterface: *MyInterface is pointer to interface, not interface

我尝试做类型断言:object.(MyInterface),但这也不起作用.

I tried doing type assertion: object.(MyInterface), but that doesn't work either.

我该怎么做?

推荐答案

如错误所示,

在AcceptInterface的参数中不能使用对象(类型* MyType)作为类型* MyInterface:* MyInterface是指向接口而不是接口的指针

cannot use object (type *MyType) as type *MyInterface in argument to AcceptInterface: *MyInterface is pointer to interface, not interface

这意味着它期望一个 interface 值,而不是一个指针.

This means that it is expecting an interface value, not a pointer.

如果将指针更改为代码中的值(通过删除& * ),程序将无错误运行:

If you change the pointers to values in your code (by removing the & and *), the program will run with no errors:

package main


type MyInterface interface {
    Test()
}

type MyType struct {

}
func (m MyType) Test(){}

func AcceptInterface(i MyInterface){
}

func main() {

    object := MyType{}
    AcceptInterface(object)
}

播放

如果您仍想使用指针作为参数,则Go语言中有两个重要的部分需要注意

If you still want to use a pointer as an argument, there are two important parts of the Go language to note

  1. Go Spec 中了解 exacly 是什么适合实例的变量:

  1. From the Go Spec on what exacly is a variable that fits an instance:

接口类型的变量可以使用方法集合存储任何类型的值,该方法集是接口的任何超集.

A variable of interface type can store a value of any type with a method set that is any superset of the interface.

  • 转到Spec 中,了解哪些指针已自动取消引用:

  • From the Go Spec on what pointers being automatically dereferenced:

    与选择器一样,使用指针使用值接收器对非接口方法的引用将自动取消引用该指针: pt.Mv 等效于(* pt).Mv [and]与方法调用一样,使用指针指针接收器使用可寻址值对非接口方法的引用将自动采用该值的地址: t.Mp 等效于(& t).Mp.

    As with selectors, a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv [and] as with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp.

  • 这两个要点很重要,因为将它们结合起来可以解释指向变量的指针仍然可以适合实例.这是因为Go编译器自动取消了指针的方法集的引用(并且自从所引用的变量可以适合实例,指针也可以)

    Those two points are important, because when combined they explain that pointers to variables can still fit instances. This is because the pointer's method set is automatically dereferenced by the Go compiler (and since the variable it is referencing can fit an instance, the pointer can, too)!

    实际上,这意味着要查看指针是否适合实例,必须将实例声明为 value ,并将指针声明为 pointer .

    In action, this means that in order to see if a pointer fits an instance, you have to declare the instance as a value and the pointer as a pointer.

    如果运行此代码:

    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 声明中?

    you will see that there are no errors! Notice how there is an & in the object declaration, but no * in the i declaration?

    这篇关于为接受接口的函数传递结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆