67
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?

user1091856
  • 3,032
  • 6
  • 31
  • 42

2 Answers2

130

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```
davetron5000
  • 24,123
  • 11
  • 70
  • 98
  • 10
    Wouldn't all embedded fields be promoted? I've tried to run (https://play.golang.org/p/zB3Qgkhl84D) an example from https://medium.com/golangspec/promoted-fields-and-methods-in-go-4e8d7aefb3e3 and the second embedded field is also promoted – hashlash Oct 27 '20 at 03:55
  • 1
    @hashlash yes, they are – yyFred Dec 25 '20 at 03:26
  • 4
    If two anonymous fields have all distinct fields, all are promoted. If two anonymous fields happen to have a field with the same name, that field is not promoted due to ambiguity. If you try to access such a field with promotion, you get the `ambiguous selector` compilation error. – Somu Nov 08 '22 at 04:08
24

See "Embedding in Go ": you embed an anonymous field in a struct: this is generally used with an embedded struct, not a basic type like string. That type has no "promoted field" to expose.

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.

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 "Embeddding when to use pointer".

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

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • So struct types can inherit methods from another class just like in OOP, with the exception that it only inherits methods, not properties, correct? – user1091856 Jan 18 '15 at 21:19
  • @user1091856 inherit is not an ideal term for Go, which insists more on composition. But yes, it enable some kind of inheritance (https://geekwentfreak-raviteja.rhcloud.com/blog/2014/03/06/golang-inheritance-by-embedding/, http://golangtutorials.blogspot.fr/2011/06/inheritance-and-subclassing-in-go-or.html, http://stackoverflow.com/a/1761393/6309, http://spf13.com/post/is-go-object-oriented/) – VonC Jan 18 '15 at 21:28