【问题标题】:Golang embedded struct typeGolang 嵌入式结构体类型
【发布时间】:2017-12-24 16:03:13
【问题描述】:

我有这些类型:

type Value interface{}

type NamedValue struct {
    Name  string
    Value Value
}

type ErrorValue struct {
    NamedValue
    Error error
}

我可以使用v := NamedValue{Name: "fine", Value: 33},但我不能使用e := ErrorValue{Name: "alpha", Value: 123, Error: err}

好像嵌入语法没问题,但是用起来不行?

【问题讨论】:

    标签: go struct embedding composite-literals


    【解决方案1】:

    嵌入式类型是(未命名的)字段,由非限定类型名称引用。

    Spec: Struct types:

    使用类型声明但没有显式字段名称的字段是匿名字段,也称为嵌入字段或结构中类型的嵌入。必须将嵌入类型指定为类型名称T 或指向非接口类型名称*T 的指针,而T 本身可能不是指针类型。 不合格的类型名作为字段名。

    那就试试吧:

    e := ErrorValue{NamedValue: NamedValue{Name: "fine", Value: 33}, Error: err}
    

    如果您在复合文字中省略字段名称也可以:

    e := ErrorValue{NamedValue{"fine", 33}, err}
    

    尝试Go Playground 上的示例。

    【讨论】:

    • 在使用嵌入类型的结构中命名字段时是否有最佳实践?
    • @SeanPianka 你是什么意思?命名字段和嵌入存在争议:嵌入字段是匿名字段。
    • 省略字段名称确实如前所述,但是如果您的结构有很多字段,那么不幸的是,您还需要传递它们。例如对于具有四个属性的结构,如果您的嵌入式结构是第一个字段之一,那么您需要像 ErrorValue{nil, NamedValue{"fine", 33}, nil, nil} 一样对其进行初始化,这看起来不像传递嵌入式结构的非限定类型名称那么干净。提到的第一种方法要好一些,但我不禁觉得它有点不必要的复杂和笨拙(至少与 Python 之类的语言相比)
    【解决方案2】:

    对于深度嵌套的结构,接受的答案的语法有点冗长。比如这个:

    package main
    
    import (
        "fmt"
    )
    
    type Alternative struct {
        Question
        AlternativeName string
    }
    
    type Question struct {
        Questionnaire
        QuestionName  string
    }
    
    type Questionnaire struct {
        QuestionnaireName string
    }
    
    func main() {
        a := Alternative{
            Question: Question{
                Questionnaire: Questionnaire{
                    QuestionnaireName: "q",
                },
            },
        }
        fmt.Printf("%v", a)
    }
    

    (Go playground)

    可以这样改写:

    a := Alternative{}
    a.QuestionnaireName = "q"
    

    【讨论】:

      【解决方案3】:

      除了icza的精彩回答。

      你可以这样做:

      v := NamedValue{Name: "fine", Value: 33}
      e := ErrorValue{NamedValue:v, Error: err}
      

      它工作得很好。查看示例Here

      【讨论】:

        猜你喜欢
        • 2013-10-17
        • 2014-08-11
        • 2022-11-22
        • 1970-01-01
        • 2015-05-16
        • 1970-01-01
        • 2021-06-20
        • 2019-09-15
        相关资源
        最近更新 更多