簡體   English   中英

嵌入式結構

[英]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

類型聲明和嵌入之間存在很大差異,您可以通過手動在NodeProperties之間進行類型轉換來使最后一個示例工作:

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
}

但很明顯這不是你想要的,你想要一個帶有類型別名語法的結構嵌入,這在是不可能的,我認為你應該堅持你的第一種方法並忽略代碼冗余的事實並且丑陋的 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM