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 :-)
}