...

/

Anonymous Fields and Embedded Structs

Anonymous Fields and Embedded Structs

In the first part of this lesson, you'll study how to make structs with nameless fields and how to use them. In the second part, you'll see how to embed a struct inside another struct and use it.

Definition

Sometimes, it can be useful to have structs that contain one or more anonymous (or embedded) fields that are fields with no explicit name. Only the type of such a field is mandatory, and the type is then also the field’s name. Such an anonymous field can also be itself a struct, which means structs can contain embedded structs. This compares vaguely to the concept of inheritance in OO-languages, and as we will see, it can be used to simulate a behavior very much like inheritance. This is obtained by embedding or composition. Therefore, we can say that in Go composition is favored over inheritance.

Consider the following program:

Press + to interact
package main
import "fmt"
type innerS struct {
in1 int
in2 int
}
type outerS struct {
b int
c float32
int // anonymous field
innerS // anonymous field
}
func main() {
outer := new(outerS)
outer.b = 6
outer.c = 7.5
outer.int = 60
outer.in1 = 5
outer.in2 = 10
fmt.Printf("outer.b is: %d\n", outer.b)
fmt.Printf("outer.c is: %f\n", outer.c)
fmt.Printf("outer.int is: %d\n", outer.int)
fmt.Printf("outer.in1 is: %d\n", outer.in1)
fmt.Printf("outer.in2 is: %d\n", outer.in2)
// with a struct-literal:
outer2 := outerS{6, 7.5, 60, innerS{5, 10}}
fmt.Println("outer2 is: ", outer2)
}

In the above code, at line 4, we make a struct of type innerS containing two integer fields in1 and in2. At line 9, we make another struct of type outerS with two fields b (an integer) and c (a float32 number). That’s not all. We also have two more fields that are anonymous fields. One is of type int (see line 13), and the other is of type innerS (see line 14). They are anonymous fields because they have no explicit names.

Now, look at main. We make an outerS variable outer via the new function at line 18. In the next few lines, we are giving the values to its fields. The fields b and c of outer are given values at line 19 and line 20, respectively. Now, it’s the turn for anonymous fields of outer.

To store data in an anonymous field or get access to the data, we use the name of the data type, e.g. outer.int. A consequence is that we can only have one anonymous field of each data type in a struct. Look at line 21. We are assigning the value of 60 to the int type anonymous field declared at line 13. But how to ...