Golang嵌入式结构

时间:2015-12-04 01:34:22

标签: go

是否可以在不使用嵌入式结构的情况下继承类型的方法?

第一段代码是工作代码,它将Property结构嵌入Node,我可以调用node.GetString Properties {{1} }}。我不喜欢这件事是我初始化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,我发现将相同的方法添加到嵌入Properties

的所有结构中是多余的

我想更准确的问题,我想使用Node中的Properties方法而无需初始化number

2 个答案:

答案 0 :(得分:3)

所以你遇到了Go在这里的特质。嵌入是一个结构的方法可以被“提升”出现在另一个结构上的唯一方法。虽然type Node Properties应该在Properties上公开Node方法感觉很直观,但该语法的效果是Node采用Properties的内存布局但不是任何方法。

它没有解释为什么要做出这种设计选择,但Go Spec至少在干燥的情况下是特定的。如果您完全按原样阅读,没有解释,则非常准确:

  

接口类型的方法集是它的接口。任何其他类型T的方法集由声明的所有方法组成   接收器类型为T

GetString有一个类型为Properties而不是Node的接收器,严肃地说,就像你是一个没有想象力的会计师那样解释规范。随着说:

  

其他规则适用于包含匿名字段的结构,如结构类型一节中所述。

     

...

     

如果x.f是表示该字段或方法f的合法选择器,则会调用struct x中匿名字段的字段或方法f。

     

提升字段的作用类似于结构的普通字段,但它们除外   不能在结构的复合文字中用作字段名称。

     

给定结构类型S和名为T的类型,提升的方法是   包含在结构的方法集中,如下所示:

     
      
  • 如果S包含匿名字段T,则方法设置为S和* S.   包括与接收器T的推广方法。* S的方法集也   包括带接收器* T的推广方法。
  •   
  • 如果S包含匿名   field * T,S和* S的方法集都包括提升方法   接收器T或* T。
  •   

关于复合文字的这一行强迫你在你创建的每个Properties内声明Node

P.S。嗨杰夫!

答案 1 :(得分:1)

对上一个问题的简短回答只是

中的类型声明和嵌入之间存在很大差异,您可以通过在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
}

但显然这不是你想要的,你想要一个带有类型别名的语法的结构嵌入,这在中是不可能的,我认为你应该坚持你的第一种方法并忽略代码冗余和丑陋的事实。