Golang嵌入式结构类型

huangapple go评论87阅读模式
英文:

Golang embedded struct type

问题

我有以下类型:

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}

似乎嵌入语法是正确的,但是使用它不起作用?

英文:

I have these types:

type Value interface{}

type NamedValue struct {
    Name  string
    Value Value
}

type ErrorValue struct {
    NamedValue
    Error error
}

I can use v := NamedValue{Name: "fine", Value: 33}, but I am not able to use e := ErrorValue{Name: "alpha", Value: 123, Error: err}

Seems that embedding syntax was ok, but using it doesn't work?

答案1

得分: 46

嵌入类型是(未命名的)字段,通过未限定的类型名称进行引用。

规范:结构类型:

声明了类型但没有显式字段名的字段是_匿名字段_,也称为_嵌入字段_或将类型嵌入结构中。嵌入类型必须指定为类型名称T或非接口类型名称*T的指针,并且T本身不能是指针类型。未限定的类型名称充当字段名。

因此,尝试:

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

如果在复合字面量中省略字段名,也可以正常工作:

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

Go Playground上尝试这些示例。

英文:

Embedded types are (unnamed) fields, referred to by the unqualified type name.

Spec: Struct types:

> A field declared with a type but no explicit field name is an anonymous field, also called an embedded field or an embedding of the type in the struct. An embedded type must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.

So try:

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

Also works if you omit the field names in the composite literal:

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

Try the examples on the Go Playground.

答案2

得分: 6

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

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)
}

可以改写成这样:

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

Go playground

英文:

For deeply nested structs, the accepted answer's syntax is a little verbose. For example, this :

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)

Could be rewritten like this:

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

答案3

得分: 4

除了icza提供的精彩答案之外,你还可以简单地这样做:

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

它完全可以正常工作。在这里查看示例。

英文:

In addition to the wonderful answer by icza.

you can simply do this:

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

and it works just fine. checkout the example Here

huangapple
  • 本文由 发表于 2017年7月19日 19:46:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/45189605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定