Golang的值接收者方法能否实现多态 对比指针接收者的接口实现差异
值接收者可以实现接口并支持多态,但不能修改接收者状态;指针接收者可修改对象状态且只能由指针实现接口。1. 值接收者方法可被值或指针调用,适合不修改状态的场景;2. 指针接收者方法只能由指针实现接口,适用于需要修改状态的情况;3. 值类型赋值给接口时自动复制,指针接收者方法修改的是原对象;4. 多态的建立与否决方法集相关,而方法集与接收者类型相关。
在Golang中,接收器的方法可以是值类型或者指针类型。很多人都会遇到一个问题:值接收器的方法不能实现多态?和指针接收器相比,接口实现有什么差异?
答案是:值接收器可以在一定修改架构中实现多态,但在某些场景下会有前面的,特别是当你需要接收时值接收者的状态时。值接收者也能实现接口
Go语言中的接口实现是隐式的,只要某种类型实现了接口定义的所有方法,它就“实现了”该接口。而这些方法的接收者无论是值还是指针,都可以满足接口的要求。
立即学习“go语言免费学习笔记(深入)”;
举个例子:type Animal 接口 { Speak() string}type Dog struct{}func (d Dog) Speak() string { return quot;Woof!quot;}登录后复制
这里 Dog 登录后复制 是一个结构体,它的 Speak() 登录后复制方法使用的是值接收者,但它仍然实现了 Animal 登录后复制接口。
你可以这样用:var a Animal = Dog{} // OKfmt.Println(a.Speak())登录后复制
所以结论是:值接收者可以实现接口,并支持多态。指针接收者的优势:能修改接收者本身
那为什么很多代码都习惯用指针接收者来实现接口呢?
这是方法如果需要接收修改接收者内部的状态,就必须用指针接收者。比如下面的例子:type Counter struct { count int}func (c Counter) incr() { c.count }func (c *Counter) GetCount() int { return c.count}登录后复制
如果你这样调用:var c Counterc.Incr()fmt.Println(c.GetCount()) // 输出0登录后复制
你会发现count登录后复制并没有增加。因为Incr()登录后复制 是值接收者,它的操作是副本。而 GetCount() 登录后复制是修改指针接收者状态,访问的是原始对象。
所以,在需要接收者状态的情况下,必须使用指针接收者。实现接口时,值接收者和指针接收者的区别
值接收者方法:可以被值类型和指针类型调用。如果方法不修改接收者状态,值接收者更安全、节省内存(不会产生额外指针接收者) )。当你把一个值赋给接口变量时,Go会自动复制这个值。
指针接收者方法:只能由指针类型调用(但Go允许你写成值类型调用,它会自动取地址)。还有修改原对象,需要适合改变状态的方法。如果你尝试用值类型去赋给接口变量,只有当所有方法都是值接收者时才可以通过编译。
举个例子说明差异:type Animal interface { Move()}type Cat struct{}func (c Cat) Move() {} // 值接收者type Bird struct{}func (b *Bird) Move() {} // 指针接收者var a1 Animal = Cat{} // OKvar a2 Animal = amp;Bird{} // OKvar a3 Animal = Bird{} //编译错误!Bird没有实现动物接口登录后复制
可以,只有对于指针接收器方法来说,确定指针接收器才能满足接口。总结一下值接收器方法实现接口,也可以支持多态。指针接收器更适合需要修改对象状态的场景。看到值接收器方法对值和指针接收;指针接收器只能由指针实现接口。多态是否成立,连接方法集(方法) set),而方法集又与接收者类型有关。
基本上就这些。
以上就是Golang的值接收者方法能否实现多态 对比指针接收器的接口实现差异的详细内容,更多请关注乐哥常识网其他相关文章!