2015-07-19 125 views
3

在文檔effective Go它指出:爲什麼沒有爲命名指針類型定義方法?

隨着我們ByteSize看到的,方法可以爲任何命名類型 (除了指針定義...

​​

它接着以提供一個指針作爲接收器的例子:

func (p *ByteSlice) Append(data []byte) { 
    slice := *p 
    // Body as above, without the return. 
    *p = slice 
} 

是不是這樣相反ct?或者這是否意味着這是無效的:

type ByteSlice []byte 
type Pb *ByteSlice 
func (p Pb) Append(data []byte) []byte { 
} 

雖然它看起來就像一個typedef!

回答

2

命名指針類型可能會導致歧義,像這樣:

type T int 

func (t *T) Get() T { 
    return *t + 1 
} 

type P *T 

func (p P) Get() T { 
    return *p + 2 
} 

func F() { 
    var v1 T 
    var v2 = &v1 
    var v3 P = &v1 
    fmt.Println(v1.Get(), v2.Get(), v3.Get()) 
} 

在根據當前規範後一種情況下(ESP v3),它是曖昧這Get()方法應被調用。是的,沒有理由不能定義方法解決方案,但是對於已經有解決方案的東西來說,這是一種更加細節的方法。

+0

我們正在猜測語言中沒有的東西的語義,但是如果從* I到* P的轉換自動發生(因此您的代碼段是明確的),這將是非常令人驚訝的。如果'P'被定義爲'type P I',那麼'I(0).Get()'已經是明確的了,我不明白爲什麼添加指針會產生任何影響。 –

+0

我已經去了P.Get – Sridhar

+0

@PaulHankin:是的,那不是我所希望的那麼清楚。爲了強調自動類型轉換問題,我稍微擴展了它。請注意,沒有明確的原因,它*無法被定義,但是因爲它不能解決真正的問題,並且只會使代碼不那麼清晰,所以它永遠不會作爲值得添加到語言中的功能傳遞。 – JimB

2

作爲指針的指定類型與指向指定類型的指針不同。

這是語言參考這樣說:

該參數部分必須聲明一個參數,接收器。 其類型必須是T或* T形式(可能使用圓括號) 其中T是類型名稱。由T表示的類型被稱爲接收機基地類型 ;它不能是指針或接口類型,並且它必須在與方法相同的包中聲明的 。

這很清楚:如果T表示指針類型,則不能將其用作方法接收器。

請注意此處引用的注意語言:短語「其類型必須是T或T *形式」是指方法接收方的語法級規範(即類型的「表單」 )。這不同於「用T表示的類型」這個短語,它是在談論T命名的類型(也就是類型「表示」的類型)。

+0

足夠清楚,這就是有效的Go和語言規範所說的文檔。問題是爲什麼? – Sridhar

+0

我期望答案會沿着它會使語言更加複雜,並不清楚會有什麼好處。 –

+0

夠公平的。另一個答案確實提供了一個潛在併發症的例子。天真地,類型看起來像是一個typedef對我來說 - 不清楚爲什麼應該限制使用。 – Sridhar

相關問題