规则是,方法只能在命名类型和指向命名类型的指针上定义。
对于以下code,
package main
type Cat struct {
}
func (c Cat) foo() {
// do stuff_
}
func (c *Cat) foo() {
// do stuff_
}
func main() {
}
编译器给出错误:
main.go:10: method redeclared: Cat.foo
method(Cat) func()
method(*Cat) func()
以上代码定义,
指定类型(foo()
)和
Cat
方法foo()
用于指向命名类型(*Cat
)的指针。
问题:
对于GO编译器,为什么要考虑为不同类型定义的方法 相同?
答案 0 :(得分:2)
在Go中,接收器是一种语法糖。函数(c Cat) foo()
的实际运行时签名是foo(c Cat)
。接收器移动到第一个参数。
Go不支持名称重载。在包中只能有一个名为foo
的函数。
说完上面的陈述后,你会发现有两个名为foo
的函数有不同的签名。这种语言不支持它。
你不能在Go中这样做。经验法则是为指针接收器编写一个方法,只要有指针或值,Go就会使用它。
如果您仍需要两种变体,则需要对方法命名不同。
答案 1 :(得分:0)
例如,你可以建模这样的猫科动物行为:
package main
import (
"fmt"
)
type Growler interface{
Growl() bool
}
type Cat struct{
Name string
Age int
}
// *Cat is good for both objects and "object references" (pointers to objects)
func (c *Cat) Speak() bool{
fmt.Println("Meow!")
return true
}
func (c *Cat) Growl() bool{
fmt.Println("Grrr!")
return true
}
func main() {
var felix Cat // is not a pointer
felix.Speak() // works :-)
felix.Growl() // works :-)
var ginger *Cat = new(Cat)
ginger.Speak() // works :-)
ginger.Growl() // works :-)
}