首頁 >後端開發 >Golang >為什麼具有值接收器的 Go 結構不能實作與指標接收器的介面?

為什麼具有值接收器的 Go 結構不能實作與指標接收器的介面?

Patricia Arquette
Patricia Arquette原創
2024-12-04 01:40:11571瀏覽

Why Can't Go Structs with Value Receivers Fulfill Interfaces with Pointer Receivers?

為什麼 Go 結構體變數不能實作有指標接收器的介面?

在 Go 中,結構體方法可以有任一值接收器(操作直接作用於結構體值)或指標接收器(作用於指向結構體的指標)。在實作介面時,根據介面方法的接收者類型,哪些類型可以滿足介面有一些微妙的限制。

考慮以下程式碼:

type greeter interface {
    hello()
    goodbye()
}

type tourGuide struct {
    name string
}

我們可以定義方法tourGuide 的值和指標接收器:

func (t tourGuide) hello() {
    fmt.Println("Hello", t.name)
}

func (t *tourGuide) goodbye() {
    fmt.Println("Goodbye", t.name)
}

現在,這是關鍵區別:

  • tourGuide的變數或副本可以呼叫值和指標接收器方法:

    var t1 tourGuide = tourGuide{"James"}
    t1.hello()   // works
    t1.goodbye() // works
  • 但是,介面變數只能是從可以實現與介面具有相同接收器類型的所有介面方法的類型分配本身:

    var g2 greeter = &t2 // works because *tourGuide implements greeter's pointer receiver methods
    
    // illegal: t1 is not assignable to g1
    // var g1 greeter = t1 // error: cannot use tourGuide as type greeter in assignment because tourGuide does not implement greeter (hello method has value receiver)

那麼,為什麼t1不能實作greeter介面呢?

原因是greeter介面中的hello()方法有一個指標接收器,這表示它需要一個指向tourGuide值的指標作為接收器。但是,t1 是一個變數(不是指標)。儘管值變數是可尋址的,但介面值保留儲存值的副本,而不是引用。因此,當將值變數指派給介面變數時,它會建立一個新的副本,該副本無法取消引用並作為指標接收器方法的接收器傳遞。

綜上所述,在使用指標接收器方法實作介面時,只能使用指標實作類型可以滿足介面。值變數或副本不可指派給此類接口,因為它們無法提供所需的指標接收器類型。

以上是為什麼具有值接收器的 Go 結構不能實作與指標接收器的介面?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn