首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌入式结构

嵌入式结构
EN

Stack Overflow用户
提问于 2015-12-04 09:34:22
回答 2查看 9.2K关注 0票数 10

有没有可能在不使用嵌入式结构的情况下继承类型的方法?

第一段代码是在Node中嵌入Property结构的工作代码,我可以调用node.GetString,这是Properties上的一个方法。我不喜欢这一点的是,当我初始化Node时,我有(?)初始化其中的Properties结构。有什么办法可以解决这个问题吗?

代码语言:javascript
复制
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结构。以下代码不起作用,但可能清楚我的目标是什么。

代码语言:javascript
复制
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方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-04 16:06:28

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

它没有解释为什么做出这种设计选择,但Go Spec至少是特定的,如果是dry。如果你完全按照它的样子读,没有任何解释,它是非常准确的:

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

GetString有一个Properties类型的接收器,而不是Node类型,说真的,就像你是一个没有想象力的会计一样来解释这个规范。如上所述:

进一步的规则适用于包含匿名字段的结构,如结构类型部分所述。

..。

如果x.f是表示某个字段或方法f的合法选择器,则结构x中匿名字段的字段或方法f称为promoted。

提升字段的行为类似于结构的普通字段,不同之处在于它们不能用作结构的复合文本中的字段名。

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

  • 如果S包含匿名字段T,则S和*S的方法集都包括接收方为T的升级方法。*S的方法集还包括接收方为*T的升级方法。
  • 如果S包含匿名字段*T,则S和*S的方法集都包括接收方为T或*T的升级方法。

关于复合文字的这一行迫使您在创建的每个Node中声明Properties

附注:嗨,杰夫!

票数 4
EN

Stack Overflow用户

发布于 2015-12-04 16:08:10

最后一个问题的简短答案是No

golang中,类型声明和嵌入之间有很大的不同,您可以通过手动在NodeProperties之间进行类型转换来使最后一个示例工作

代码语言:javascript
复制
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中是不可能的,我认为你应该坚持你的第一种方法,忽略代码冗余和丑陋的事实。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34079466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档