[英]Embedded struct
是否可以在不使用嵌入式結構的情況下繼承類型的方法?
第一段代碼是在Node
中嵌入Property
結構的工作代碼,我可以調用node.GetString
,這是Properties
上的一個方法。 我不喜歡這個的事情是當我初始化Node
我有(?)來初始化其中的Properties
結構。 有沒有解決的辦法?
package main
import "fmt"
type Properties map[string]interface{}
func (p Properties) GetString(key string) string {
return p[key].(string)
}
type Nodes map[string]*Node
type Node struct {
*Properties
}
func main() {
allNodes := Nodes{"1": &Node{&Properties{"test": "foo"}}} // :'(
singleNode := allNodes["1"]
fmt.Println(singleNode.GetString("test"))
}
最終,我想做如下事情。 Node
的類型為Properties
並且初始化也不需要初始化Property
結構。 以下代碼不起作用,但可能很清楚我的目標是什么。
package main
import "fmt"
type Properties map[string]interface{}
func (p Properties) GetString(key string) string {
return p[key].(string)
}
type Nodes map[string]*Node
type Node Properties
func main() {
allNodes := Nodes{"1": &Node{"test": "foo"}} // :)
singleNode := allNodes["1"]
fmt.Println(singleNode.GetString("test")) // :D
}
我將添加更多使用Properties
方法的結構,這就是我要問的原因。 如果我只有Node
,我就會有Node
方法並完成。 但是因為我將擁有的不僅僅是Node
所以我發現將相同的方法添加到所有嵌入Properties
的結構中是多余的
我想更多的是確切的問題,我想使用Node
Properties
方法而不必初始化Properties
。
所以你在這里遇到了 Go 的特性。 嵌入是一個結構體的方法可以被“提升”以出現在另一個結構體上的唯一方式。 雖然它直觀的感覺是type Node Properties
應該暴露Properties
上的方法Node
,這句法的這種效果是Node
采取的內存布局Properties
,但不是它的任何方法。
它沒有解釋為什么做出這種設計選擇,但Go Spec在干燥時至少是特定的。 如果你完全按照它出現的方式閱讀它,沒有解釋,它是非常准確的:
接口類型的方法集就是它的接口。 任何其他類型 T 的方法集由所有聲明為接收器類型 T 的方法組成
GetString
有一個Properties
類型的接收器,而不是Node
,認真地,像你是一個沒有想象力的會計師一樣解釋規范。 照這樣說:
更多規則適用於包含匿名字段的結構,如結構類型部分所述。
...
如果 xf 是表示該字段或方法 f 的合法選擇器,則結構 x 中匿名字段的字段或方法 f 被稱為提升。
提升字段的作用類似於結構的普通字段,只是它們不能用作結構的復合文字中的字段名稱。
給定一個結構類型 S 和一個名為 T 的類型,提升的方法包含在結構的方法集中,如下所示:
- 如果 S 包含匿名字段 T,則 S 和 *S 的方法集都包含接收者 T 的提升方法。 *S 的方法集還包括接收者 *T 的提升方法。
- 如果 S 包含匿名字段 *T,則 S 和 *S 的方法集都包含帶有接收者 T 或 *T 的提升方法。
關於復合文字的那一行是強制您在您創建的每個Node
內聲明Properties
東西。
ps嗨,傑夫!
您最后一個問題的簡短答案是No 。
golang 中的類型聲明和嵌入之間存在很大差異,您可以通過手動在Node
和Properties
之間進行類型轉換來使最后一個示例工作:
package main
import "fmt"
type Properties map[string]interface{}
func (p Properties) GetString(key string) string {
return p[key].(string)
}
type Nodes map[string]*Node
type Node Properties
func main() {
allNodes := Nodes{"1": &Node{"test": "foo"}} // :)
singleNode := allNodes["1"]
fmt.Println(Properties(*singleNode).GetString("test")) // :D
}
但很明顯這不是你想要的,你想要一個帶有類型別名語法的結構嵌入,這在golang 中是不可能的,我認為你應該堅持你的第一種方法並忽略代碼冗余的事實並且丑陋的 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.