繁体   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