亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 如何將方法綁定到對象?

Go 如何將方法綁定到對象?

Go
慕森王 2022-07-11 10:40:49
前幾天剛開始學習 Go。今天,我們在調試一段代碼時,發現了一些似乎違反 Go 直覺的事情。首先,我們定義了一個接口和一個實現它的數據結構。type Executer interface {    Execute()}type whatever struct {    name string}func (this *whatever) Execute() {    log.Println(this.name)}現在考慮我有一個 nil 指針whatever,我嘗試調用該方法Execute。在我迄今為止使用的其他面向對象語言中,這將在調用方法(即w.Execute())時調用空指針錯誤,因為對象指針為空。Execute有趣的是,在 Go 中,該方法被調用,當我嘗試取消引用時,該方法出現空指針錯誤this.name。為什么不在調用方法的時候呢?func main() {    var w *whatever    w.Execute()}那么,我現在想要了解的是這怎么可能?這是否意味著 Go 僅在編譯時進行早期方法綁定,而在運行時沒有方法與特定對象的綁定?
查看完整描述

1 回答

?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

接收者只是函數的“普通”參數。普通參數可以是指針類型。如果是,則允許您nil作為參數傳遞,這是完全有效的。您需要記住的只是不要取消引用nil指針參數。這同樣適用于特殊的接收器參數。如果它是一個指針,它可能是nil,你不能取消引用它。


規范:方法聲明:


接收者是通過方法名稱前面的額外參數部分指定的。


...該方法被稱為綁定到它的接收者基類型,并且方法名稱僅在type或的選擇器中可見。T*T


允許nil接收器值不僅是不被禁止的,它還有實際用途。例如,請參閱測試嵌套結構中的 nil 值。


null在 Java 中,您也可以在對象上調用靜態方法。確實你不能在 Go 中做同樣的事情,因為 Go 沒有像static,public等修飾符private。在 Go 中只有導出和非導出的方法(由它們的名字的后一個暗示)。


但是 Go 也提供了類似的東西:方法表達式和方法值。如果您有一個接收器類型的方法m,T則表達式T.m將是一個函數值,其簽名包含m接收器類型“前綴”的參數和結果類型。


例如:


type Foo int


func (f Foo) Bar(s string) string { return fmt.Sprint(s, f) }


func main() {

    fooBar := Foo.Bar // A function of type: func(Foo, string) string

    res := fooBar(1, "Go")

    fmt.Println(res)

}

Foo.Bar將是一個帶有 type 的函數func (Foo, string) string,你可以像任何其他普通函數一樣調用它;而且您還必須將接收器作為第一個參數傳遞。上面的應用程序輸出(在Go Playground上試試):


Go1

稍微“前進”,我們不需要存儲Foo.Bar在變量中,我們可以直接調用Foo.Bar:


fmt.Println(Foo.Bar(1, "Go"))

輸出相同(在Go Playground上嘗試)?,F在這幾乎看起來像staticJava 中的方法調用。


而作為“最后”步驟,當我們對自身的值(而不是類型標識符)使用上述表達式時Foo,我們會得到方法值,這會保存接收者,因此方法值的類型不包括接收者,它的簽名將是方法的簽名,我們可以調用它而無需傳遞接收者:


var f Foo = Foo(1)

bar := f.Bar

fmt.Println(bar("Go"))

這將再次輸出相同的內容,請在Go Playground上嘗試。


查看完整回答
反對 回復 2022-07-11
  • 1 回答
  • 0 關注
  • 220 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號