值接收者可以实现接口并支持多态,但不能修改接收者状态;指针接收者可修改对象状态且仅能由指针实现接口。1. 值接收者方法可被值或指针调用,适合不修改状态的场景;2. 指针接收者方法只能由指针实现接口,适用于需修改状态的情况;3. 值类型赋值给接口时自动复制,指针接收者方法修改的是原对象;4. 多态成立与否取决于方法集,而方法集与接收者类型相关。

在Golang中,方法的接收者可以是值类型或者指针类型。很多人会遇到一个问题:值接收者的方法能不能实现多态?和指针接收者相比,接口实现有什么差异?

答案是:值接收者可以在一定程度上实现多态,但在某些场景下会有局限,特别是当你需要修改接收者的状态时。

Go语言中的接口实现是隐式的,只要某个类型实现了接口定义的所有方法,它就“实现了”该接口。而这些方法的接收者不管是值还是指针,都可以满足接口的要求。
立即学习“go语言免费学习笔记(深入)”;
举个例子:

type Animal interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}这里
Dog
Speak()
Animal
你可以这样用:
var a Animal = Dog{} // OK
fmt.Println(a.Speak())所以结论是:值接收者可以实现接口,并支持多态。
那为什么很多代码都习惯用指针接收者来实现接口呢?
这是因为如果方法需要修改接收者内部的状态,就必须用指针接收者。比如下面的例子:
type Counter struct {
count int
}
func (c Counter) Incr() {
c.count++
}
func (c *Counter) GetCount() int {
return c.count
}如果你这样调用:
var c Counter c.Incr() fmt.Println(c.GetCount()) // 输出 0
你会发现
count
Incr()
GetCount()
所以,在需要修改接收者状态的情况下,必须使用指针接收者。
值接收者方法:
指针接收者方法:
举个例子说明差异:
type Animal interface {
Move()
}
type Cat struct{}
func (c Cat) Move() {} // 值接收者
type Bird struct{}
func (b *Bird) Move() {} // 指针接收者
var a1 Animal = Cat{} // OK
var a2 Animal = &Bird{} // OK
var a3 Animal = Bird{} // 编译错误!Bird没有实现Animal接口可以看到,对于指针接收者方法来说,只有传入指针才能满足接口。
基本上就这些。
以上就是Golang的值接收者方法能否实现多态 对比指针接收者的接口实现差异的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号