2017-01-29 59 views
-1

規則是,方法只能在指定類型和指向指定類型的指針上定義。GO - 方法重新聲明的錯誤


對於下面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

因爲這個錯誤,我怎麼知道,爲所允許的類型來定義什麼方法? – overexchange

+1

的可能的複製[GO - 爲什麼隱式非指針的方法不能滿足接口(http://stackoverflow.com/questions/41922181/go-why-implicit-non-pointer-methods-not-satisfy-interface) –

+0

@ dev.bmax你怎麼認爲它是重複的?如果這個查詢得到答案愛德,然後請分享它 – overexchange

回答

2

在圍棋,接收器是一種語法糖。功能(c Cat) foo()的實際運行時簽名是foo(c Cat)。接收器被移動到第一個參數。

Go不支持名稱重載。包中只能使用名稱foo的一個功能。

說了上面的語句,你看會有不同的簽名命名foo兩種功能。這種語言不支持它。

你不能這樣做,在圍棋。經驗法則是爲指針接收器編寫一個方法,只要有指針或值,Go就會使用它。

如果您仍需要兩個變種,你需要不同的命名方法。

+0

函數'foo()'具有相同的簽名。在方法'(Cat)foo()'&'(* Cat)foo()'中,第一個參數是接收器類型參數,它使不同的簽名。那麼,簽名是如何相同的?編譯器不會抱怨該函數('foo')具有相同的簽名 – overexchange

+0

@overxchange如果你有'var c Cat'並調用'c.foo()'你如何消除被調用的方法的歧義? –

+0

@JonathonReinhart ** 1)**您是否問過,如果GO編譯器允許這兩種方法,那麼就說'var c Cat; c.foo()',要調用哪種方法?接收器類型'(c Cat)'是假設消除歧義的。 ** 2)**當我說'func(c * Cat)foo(){..}'爲**接收器類型('* Cat')定義方法**但不適用於接收器類型('Cat') (* Cat)foo(){..}'或'func(c Cat)foo (){..}'因爲foo方法具有不同的簽名,第一個參數與一個命名類型和第二個參數一起作爲指向命名類型的指針 – overexchange

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