我正在編寫一個示例程序來回答 SO 上的另一個問題,但發現以下代碼無法編譯這一事實讓自己有些困惑;https://play.golang.org/p/wxBGcgfs1opackage mainimport "fmt"type A struct { FName string LName string}type B struct { A}func (a *A) Print() { fmt.Println(a.GetName())}func (a *A) GetName() string { return a.FName}func (b *B) GetName() string { return b.LName}func main() { a := &A{FName:"evan", LName:"mcdonnal"} b := &B{FName:"evan", LName:"mcdonnal"} a.Print() b.Print()}錯誤是;/tmp/sandbox596198095/main.go:28: unknown B field 'FName' in struct literal/tmp/sandbox596198095/main.go:28: unknown B field 'LName' in struct literal是否可以在靜態初始值設定項中設置嵌入類型的字段值?如何?對我來說,這似乎是一個編譯器錯誤;如果我面前沒有源代碼并且熟悉類型,我會撞墻說“顯然 FName 存在于 B 上,編譯器在說什么??????!”。很快,為了搶占典型的答案,我知道最接近的工作語法是 thisb := &B{A{FName:"evan", LName:"mcdonnal"}}但我認為該語法在概念上與嵌入相矛盾,所以如果它是唯一的選擇,我會感到失望。如果這是唯一的方法,它是 Go 編譯器的短板,還是實際上存在阻止編譯器解釋我的非工作示例中的語法的理論限制?
1 回答

縹緲止盈
TA貢獻2041條經驗 獲得超4個贊
這不是編譯器錯誤,而是設計決策。語言規范只是說明:
提升字段的作用類似于結構的普通字段,只是它們不能用作結構的復合文字中的字段名稱。
我想這背后的原因是為了避免歧義。使用選擇器時有一些規則可以解決名稱沖突,并且它們必須很復雜才能滿足您的建議。最重要的是,如果您在嵌入類型的結構文字中使用嵌入結構的現有實例,則可能會產生歧義。
編輯:這是一個這種方法可能適得其反的例子:
考慮一個例子,你有一個嵌入 B 的 A 和一個你想要嵌入的 A 實例:
type A {
X int
}
type B {
A
}
做起來很簡單
b := B{ X: 1 }
并推斷應該做什么。但是如果我們已經有一個 A 的實例呢?這沒有意義:
a := A { X: 1 }
b := B { X: 2, A: a, }
您是先將 2 分配給 A 的零實例,然后再將 A 的初始化實例分配給它嗎?它是否等同于:
b := B { A: a, X: 2 } ?
它打破了初始化順序與具有字段名稱的復合文字無關的假設。
- 1 回答
- 0 關注
- 203 瀏覽
添加回答
舉報
0/150
提交
取消