Go语言中的匿名字段是什么意思?

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

Nameless fields in Go structs?

问题

包 main

导入 "fmt"

类型 myType struct {
string
}

func main() {
obj := myType{"Hello World"}

fmt.Println(obj)

}

无名字段在结构体中的目的是什么?

是否可以像使用命名字段一样访问这些字段?

英文:
package main

import "fmt"

type myType struct {
    string
}

func main() {
    obj := myType{"Hello World"}

    fmt.Println(obj)
}

What is the purpose of nameless fields in structs?

Is it possible to access these fields like you can do with named fields?

答案1

得分: 130

对于所选答案表示无意冒犯,但它没有为我澄清这个概念。

这里有两个问题。首先是匿名字段。其次是“提升”字段。

对于匿名字段,你可以使用的字段名是类型的名称。第一个匿名字段是“promoted”,这意味着你在结构体上访问的任何字段都会“通过”传递到提升的匿名字段。这展示了两个概念:

package main

import (
	"fmt"
	"time"
)

type Widget struct {
	name string
}

type WrappedWidget struct {
	Widget       // 这是提升的字段
    time.Time    // 这是另一个具有运行时名称Time的匿名字段
	price int64  // 普通字段
}

func main() {
	widget := Widget{"my widget"}
	wrappedWidget := WrappedWidget{widget, time.Now(), 1234}

	fmt.Printf("Widget named %s, created at %s, has price %d\n",
        wrappedWidget.name, // name被传递给了被提升的Widget字段,因为它是
                            // 提升的字段
        wrappedWidget.Time, // 我们通过Time访问匿名time.Time字段
        wrappedWidget.price)

	fmt.Printf("Widget named %s, created at %s, has price %d\n",
        wrappedWidget.Widget.name, // 我们也可以直接通过Widget访问Widget
                                   // 字段
        wrappedWidget.Time,
        wrappedWidget.price)
}

输出结果为:

Widget named my widget, created at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, has price 1234
Widget named my widget, created at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, has price 1234
英文:

No disrespect to the chosen answer, but it did not clarify the concept for me.

There are two things going on. First is anonymous fields. Second is the "promoted" field.

For anonymous fields, the field name you can use is the name of the type. The first anonymous field is "promoted", which means any field you access on the struct "passes through" to the promoted anonymous field. This shows both concepts:

package main

import (
	"fmt"
	"time"
)

type Widget struct {
	name string
}

type WrappedWidget struct {
	Widget       // this is the promoted field
    time.Time    // this is another anonymous field that has a runtime name of Time
	price int64  // normal field
}

func main() {
	widget := Widget{"my widget"}
	wrappedWidget := WrappedWidget{widget, time.Now(), 1234}

	fmt.Printf("Widget named %s, created at %s, has price %d\n",
        wrappedWidget.name, // name is passed on to the wrapped Widget since it's
                            // the promoted field
        wrappedWidget.Time, // We access the anonymous time.Time as Time
        wrappedWidget.price)

	fmt.Printf("Widget named %s, created at %s, has price %d\n",
        wrappedWidget.Widget.name, // We can also access the Widget directly
                                   // via Widget
        wrappedWidget.Time,
        wrappedWidget.price)
}

Output is:

Widget named my widget, created at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, has price 1234
Widget named my widget, created at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, has price 1234```

</details>



# 答案2
**得分**: 24

参见“[在Go中嵌入][1]”:你可以在一个结构体中嵌入一个[匿名字段][2]:这通常用于嵌入结构体,而不是像`string`这样的基本类型。该类型没有“提升字段”可供公开使用。

&gt; 在结构体`x`中,如果一个匿名字段的字段或方法`f`被称为**提升**,那么`x.f`是一个合法的选择器,表示该字段或方法`f`。
&gt;
&gt; 提升字段的行为类似于结构体的普通字段,只是它们不能在结构体的复合字面值中用作字段名。

(这里的`string`本身没有字段)

在“[嵌入时何时使用指针][3]”中可以看到类型嵌入的示例。

&gt; 是否可以像使用命名字段一样访问这些字段?

`fmt.Println(obj.string)`将返回`Hello World`,而不是`{Hello World}`。

  [1]: http://www.hydrogen18.com/blog/golang-embedding.html
  [2]: https://golang.org/ref/spec#Struct_types
  [3]: https://stackoverflow.com/a/27733969/6309

<details>
<summary>英文:</summary>

See &quot;[Embedding in Go ][1]&quot;: you embed an [anonymous field in a struct][2]: this is generally used with an embedded struct, not a basic type like `string`. That type has no &quot;promoted field&quot; to expose.    

&gt; A field or method `f` of an anonymous field in a struct `x` is called **promoted** if `x.f` is a legal selector that denotes that field or method `f`.
&gt;
&gt; Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct. 
 
(here `string` has no field in itself)

See an example of type embedding in &quot;[Embeddding when to use pointer][3]&quot;.

&gt; Is it possible to access these fields like you can do with named fields?

A `fmt.Println(obj.string)` would return `Hello World` instead of `{Hello World}`.


  [1]: http://www.hydrogen18.com/blog/golang-embedding.html
  [2]: https://golang.org/ref/spec#Struct_types
  [3]: https://stackoverflow.com/a/27733969/6309

</details>



huangapple
  • 本文由 发表于 2015年1月19日 04:40:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/28014591.html
匿名

发表评论

匿名网友

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

确定