2016-11-27 109 views
1

我明白接口不按照Go spec和FAQ實現帶指針參考的方法,因爲T和* T有不同的方法集(https://golang.org/doc/faq#guarantee_satisfies_interface)。爲什麼接口不能通過指針引用實現方法,而直接訪問仍然可行?

所以,這不起作用:

package main 

import (
    "fmt" 
) 

type user struct { 
    name string 
} 

type modifier interface { 
    modify() 
} 

func (u *user) modify() { 
    u.name = "My name" 
} 

func interfaceModify(m modifier) { 
    m.modify() 
} 

func main() { 
    u := user{"Default Name"} 

    interfaceModify(u) 
    fmt.Println(u.name) 
} 

和回報:

./main.go:26:不能使用u(用戶類型)的類型修飾符在爭論interfaceModify : 用戶不實現改性劑(修改方法具有指針接收器)

此作爲說明:

[...]沒有有用的方法調用獲取指針的方法。

即使在編譯器可以將值的地址傳遞給方法的情況下,如果該方法修改該值,那麼更改將在調用者中丟失。

然而,像u.modify()直接調用替換interfaceModify(u)做工作:編譯器會的ü地址,並修改其名稱屬性爲的println()確認。

因此,我們能夠在那種精確的情況下做到這一點,而不是在界面之一。我的這種差異的唯一解釋是,在interfaceModify(m modifier),我們將有ü直接拷貝到,並沒有辦法調用modify()時要匹配相應的地址。 並且,因此,宣佈從而u := &user{"Default Name"}將複製的指針(這樣的地址)ü,這就是爲什麼m.modify()是可能的。 我正確嗎?

回答

4

我想你已經明白了。 u.modify()的作品,因爲去看它作爲(&u).modify()的簡寫。 interfaceModify(&u)也可以工作。這裏有一個遊樂場,裏面有更多的參考與價值傳遞的例子。

https://play.golang.org/p/HCMtcFAhLe

package main 

import (
    "fmt" 
) 

type user struct { 
    name string 
} 

type userPointer struct { 
    user 
} 

func (up *userPointer) modify() { 
    up.name = "My name" 
} 

type modifier interface { 
    modify() 
} 

func (u user) modify() { 
    u.name = "My name" 
} 

func interfaceModify(m modifier) { 
    m.modify() 

} 

func main() { 
    u := user{"Default Name"} 
    u.modify() 
    fmt.Println(u.name) 
    interfaceModify(u) 
    fmt.Println(u.name) 

    up := userPointer{user{"Default Name"}} 
    interfaceModify(&up) 
    fmt.Println(up.name) 
    // short hand version 
    up.name = "Default Name" 
    up.modify() 
    fmt.Println(up.name) 
    // long hand version https://golang.org/ref/spec#Calls 
    up.name = "Default Name" 
    (&up).modify() 
    fmt.Println(up.name) 
} 
2

T類型不是 '& T' 類型。換句話說,指向結構體的類型指針不是結構體類型。所以如果你決定實現一個帶有指針接收器的方法,你必須使用指針而不是結構本身,因爲指針實現了方法。你的代碼只有一個字符。

變化interfaceModify(u)interfaceModify(&u)

playground

相關問題