[英]Types of Go struct methods that satisfy an interface
給出以下 Go 代碼示例:
package main
import "fmt"
type greeter interface {
hello()
goodbye()
}
type tourGuide struct {
name string
}
func (t tourGuide) hello() {
fmt.Println("Hello", t.name)
}
func (t *tourGuide) goodbye() {
fmt.Println("Goodbye", t.name)
}
func main() {
var t1 tourGuide = tourGuide{"James"}
t1.hello() // Hello James
t1.goodbye() // Goodbye James (same as (&t1).goodbye())
var t2 *tourGuide = &tourGuide{"Smith"}
t2.hello() // Hello Smith
t2.goodbye() // Goodbye Smith (same as (*t2).hello())
// illegal: t1 is not assignable to g1 (why?)
// var g1 greeter = t1
var g2 greeter = t2
g2.hello() // Hello Smith
g2.goodbye() // Goodbye Smith
}
我可以使用類型為 tourGuide t1
的變量或指向 tourGuide t2
的指針來調用結構體tourGuide
的兩種方法。 換句話說,我可以使用T
或*T
類型的變量調用帶有T
接收器的方法。 類似地,我可以調用一個方法*T
接收機使用類型的變量T
(如果T
是可尋址的)或*T
。 我知道編譯器處理這里的差異(請參閱我在代碼中的注釋)。
但是,當我們實現接口時,情況會發生變化。 在上面的代碼中,一個類型為greeter
接口的變量可以從一個指向tourGuide
的指針tourGuide
但不能從一個tourGuide
。
誰能告訴我為什么會這樣? 為什么我可以調用t1.hello()
和t1.goodbye()
但不知何故t1
對接口greeter
是不夠的?
如果您有一個指向結構的指針,那么 go 將允許您訪問結構上的屬性及其具有值類型接收器(與指針接收器相關)的函數,而無需取消引用您的指針,但這僅適用於一級指針,請參閱下面的代碼,其中我將 t2 轉換為指向tourguide
的指針,此時我需要明確取消引用它以使其重新成為指向tourguide
的指針。 將指向結構的指針的第一級視為一種特殊情況,它允許您使用語法糖來訪問值類型的屬性和函數,從而不必經常手動取消對變量的引用。
package main
import "fmt"
type greeter interface {
hello()
goodbye()
}
type tourGuide struct {
name string
}
func (t tourGuide) hello() {
fmt.Println("Hello", t.name)
}
func (t *tourGuide) goodbye() {
fmt.Println("Goodbye", t.name)
}
func main() {
var t1 tourGuide = tourGuide{"James"}
t1.hello() // Hello James
t1.goodbye() // Goodbye James (same as (&t1).goodbye())
var tmpT2 *tourGuide = &tourGuide{"Smith"}
var t2 **tourGuide = &tmpT2
(*t2).hello() // Hello Smith
(*t2).goodbye() // Goodbye Smith (same as (*t2).hello())
//illegal: t1 is not assignable to g1 (why?)
//var g1 greeter = t1
//now this is illegal too
//var g2 greeter = t2
var g3 greeter = (*t2)
g3.hello() // Hello Smith
g3.goodbye() // Goodbye Smith
}
我在這里的回答解釋了為什么 Go 會阻止您獲取存儲在接口中的值的地址。
TL;博士其因為一個指向其中,當不同類型B的值隨后被存儲在接口指向的接口的類型A的值將被無效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.