Structs in Go
By Flavio Copes
Learn how structs work in Go, a type that groups fields of different types so you can define, initialize, access with dot syntax, and even nest them.
A struct is a type that groups one or more variables under a single name. We call those variables fields, and each field can have a different type.
Structs exist because passing related values around one by one gets messy fast. A person has a name and an age. With a struct you move both together: pass them to a function, return them, store them in a slice.
Defining a struct
Here’s an example of a struct definition:
type Person struct {
Name string
Age int
}
Note that I used uppercase names for the fields, otherwise those will be private to the package and when you pass the struct to a function provided by another package, like the ones we use to work with JSON or a database, those fields cannot be accessed.
Initializing a struct
Once we define a struct we can initialize a variable with that type:
flavio := Person{"Flavio", 39}
and we can access the individual fields using the dot syntax:
flavio.Age //39
flavio.Name //"Flavio"
You can also initialize a new variable naming each field:
flavio := Person{Age: 39, Name: "Flavio"}
I prefer this form. If you later add a field to Person, every positional initialization stops compiling, because positional literals must list every field. Named fields keep working.
Naming fields also lets you set only some of them:
flavio := Person{Age: 39}
or even initialize the struct without any value:
flavio := Person{}
//or
var flavio Person
In this case every field gets its zero value: "" for strings, 0 for numbers. You can set the values later:
flavio.Name = "Flavio"
flavio.Age = 39
Structs are copied, not shared
Be careful when you pass a struct to a function. Go copies it. Changes inside the function don’t touch the original:
func birthday(p Person) {
p.Age++
}
birthday(flavio)
flavio.Age //still 39
To modify the original, pass a pointer instead:
func birthday(p *Person) {
p.Age++
}
birthday(&flavio)
flavio.Age //40
Nesting structs
Once defined, a struct is a type like int or string and this means you can use it inside other structs too:
type FullName struct {
FirstName string
LastName string
}
type Person struct {
Name FullName
Age int
}
You reach the inner fields by chaining the dot syntax:
flavio.Name.FirstName //"Flavio"