首頁  >  文章  >  後端開發  >  為什麼 Go 的 `greeter` 介面不能指派一個 `tourGuide` 值,但可以指派一個指向 `tourGuide` 的指標?

為什麼 Go 的 `greeter` 介面不能指派一個 `tourGuide` 值,但可以指派一個指向 `tourGuide` 的指標?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-20 01:38:03169瀏覽

Why can't a Go `greeter` interface be assigned a `tourGuide` value, but can be assigned a pointer to a `tourGuide`?

滿足介面的Go Struct 方法類型

給出以下Go 程式碼範例:

在上面的程式碼中,您可以使用tourGuide (t1) 類型的變數或指向tourGuide 的指標呼叫tourGuide 結構體的兩個方法(t2)。然而,當實作介面時,情況就會改變。 greeter 介面類型的變數可從指向tourGuide 的指標分配,但不能從tourGuide 值指派。為什麼會出現這種情況?

接收器類型和值語義

要理解原因,了解接收器類型和值語義的概念很重要。 Go 中的方法可以有一個值接收器或一個指標接收器。值接收器方法在值的副本上調用,而指標接收器方法在原始值上調用。

複製值時,它會建立原始值的新獨立副本。對副本所做的任何修改都不會影響原始值。這稱為值語義。

在tourGuide 範例中,hello 方法有一個值接收器,而goodbye 方法有一個指標接收器。當您呼叫 t1.hello() 時,會建立 t1 的副本,並在該副本上呼叫 hello 方法。當你呼叫 t1.goodbye() 時,goodbye 方法會在原始 t1 值上呼叫。

介面和值語意

Go 中的介面是透過值語意實現的。這表示當將值指派給介面時,會建立該值的副本。對於指標接收器方法,這表示該值的副本沒有位址,因此無法在其上呼叫該方法。

例如,當您將t1 分配給g1 時(其中是一個介面值)在以下程式碼行中:

建立了t1的副本,並在副本上實現了hello和goodbye方法。但是,由於副本沒有位址,因此無法對其呼叫 goodbye 方法。

相反,當您在以下程式碼行中將t2 指派給g2 時:

建立t2(指向tourGuide的指標)的副本,並在該指標的副本上實現hello和goodbye方法。在這種情況下,指標的副本有一個位址,因此可以在其上呼叫 goodbye 方法。

結論

綜上所述,greeter 介面類型的變數是可賦值的原因從指向tourGuide的指標而不是從tourGuide值是因為介面是透過值語義實現的。當值指派給介面時,會建立該值的副本,如果介面的方法有指標接收器,則無法在副本上呼叫它們,因為副本沒有位址。

以上是為什麼 Go 的 `greeter` 介面不能指派一個 `tourGuide` 值,但可以指派一個指向 `tourGuide` 的指標?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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