GO-方法重新声明的错误
规则是,只能在命名类型和指向命名类型的指针上定义方法GO-方法重新声明的错误,go,methods,types,Go,Methods,Types,规则是,只能在命名类型和指向命名类型的指针上定义方法 对于以下内容 编译器给出错误: main.go:10: method redeclared: Cat.foo method(Cat) func() method(*Cat) func() 上述代码定义 方法foo(),用于命名类型(Cat)和 方法foo(),用于指向命名类型(*Cat)的指针 问题: 对于GO编译器,为什么要考虑为不同类型定义的方法 同样的?在围棋中,接受者是一种句法糖。函数(c Cat)foo()的
对于以下内容
编译器给出错误:
main.go:10: method redeclared: Cat.foo
method(Cat) func()
method(*Cat) func()
上述代码定义 方法
foo()
,用于命名类型(Cat
)和
方法foo()
,用于指向命名类型(*Cat
)的指针
问题:
对于GO编译器,为什么要考虑为不同类型定义的方法
同样的?在围棋中,接受者是一种句法糖。函数
(c Cat)foo()
的实际运行时签名是foo(c Cat)
。接收器移动到第一个参数
Go不支持名称重载。一个包中只能有一个名为foo
的函数
说到上面的语句,您会看到有两个名为foo
的函数具有不同的签名。此语言不支持它
你不能在围棋中那样做。经验法则是为指针接收器编写一个方法,只要有指针或值,Go就会使用它
如果您仍然需要两种变体,则需要对方法进行不同的命名。例如,您可以对一些猫科动物的行为进行如下建模:
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 :-)
}
函数
foo()
具有相同的签名。在方法(Cat)foo()
&(*Cat)foo()
)中,第一个参数是receiver type参数,它生成不同的签名。那么,签名是如何相同的呢?编译器不会抱怨函数(foo
)具有相同的signature@overexchange如果您有var c Cat
并调用c.foo()
如何消除调用哪个方法的歧义?@JonathonReinhart 1)您是否在问,如果GO编译器同时允许这两种方法,那么在说,var c Cat;c、 foo()
,要调用哪个方法?假定接收器类型(c Cat)
可以消除歧义。2) 当我用这个错误说func(c*Cat)foo(){..}
am为receiver type(*Cat
)定义方法,而不是为receiver type(Cat
)定义方法,反之亦然3)时,为什么我应该知道我需要定义哪一种方法func(c*Cat)foo(){..}
或func(c Cat)foo(){..}
因为方法foo有不同的签名,第一个参数是带有命名类型的参数,第二个参数是指向带有此错误的命名类型的指针,我如何知道,要为允许的类型定义哪些方法?可能是@dev.bmax的重复您认为它是重复的?如果这个问题得到了答案,那么请分享它。你开始的三个线程都是一样的。你只使用一种语言特性,这对你来说毫无意义,你试图在语言方法中找到不一致的地方。但是,社区每次都证明你错了。最后,您不接受文档和示例支持的答案,因为它们与您的直觉不符。@dev.bmax在看到您的答案后,我觉得这应该是我的第一个问题。我不是来接受你的答案,而是来学习的。
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 :-)
}