Summary: in this tutorial, you will learn how to use the Go struct including defining a struct, accessing and modifying fields, and passing a struct to a function.
In Go, a struct is a composite type that groups one or more variables under a single name. These variables may have different types. They are known as the fields of the struct.
A struct in Go is similar to a class in other object-oriented programming languages such as Java and C# but it is simpler and more lightweight.
Defining a struct
To define a struct, you use the following syntax:
type structName struct {
field1 type1
field2 type2
...
}
Code language: Go (go)
In this syntax:
- First, use the
type
keyword followed by the name of the struct and thestruct
keyword. - Second, list the field names with their corresponding types within the curly braces.
For example, the following defines a struct Person
that has two fields Name
and Age
. The Name
field has type string
and the Age
field has type int
:
type Person struct {
Name string
Age int
}
Code language: Go (go)
Creating a struct instance
After having a struct, you can define a variable with the type of the struct name. For example:
var p Person
Code language: Go (go)
In this example, p
is a variable with the type Person
struct. It is called an instance of the Person
struct.
When you create a struct instance without setting its fields, Go automatically assign zero values to those fields. For example:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var p Person
fmt.Println(p)
}
Code language: Go (go)
Output:
{ 0}
Code language: Go (go)
In this example, we define the Person struct instance without setting its fields. The Name and Age are empty and zero respectively.
To print a struct variable that includes both field names and values, you use the fmt.Printf()
function with the %+v
format:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var p Person
fmt.Printf("%+v\n", p)
}
Code language: Go (go)
Output:
{Name: Age:0}
Code language: Go (go)
The following shows how to assign a value to the instance of the Person
struct:
var p Person
p = Person{"Joe", 30}
fmt.Printf("%+v\n",p)
Code language: Go (go)
Output:
{Name:Joe Age:30}
Code language: Go (go)
In this syntax, Go assigns "Joe"
to the Name
field and 30
to the Age
field respectively.
In practice, you should avoid creating a struct value using this syntax because it depends on the order of fields in the Person
struct.
If you change the order of the fields in the struct definition, you may encounter errors or unexpected behaviors.
A better approach is to explicitly specify the field names and their values when creating a struct instance:
var p Person
p = Person{Name: "Joe", Age: 30}
fmt.Printf("%+v\n", p)
Code language: Go (go)
Output:
{Name:Joe Age:30}
Code language: Go (go)
Alternatively, you can use the shorthand notation to declare and initialize a struct variable as follows:
p := Person{Name: "Joe", Age: 30}
Code language: Go (go)
This code is more concise and robust. But you can use it only inside a function.
When using a multi-line initialization, you need to place a comma after the last field:
p := Person {
Name: "Joe",
Age: 30,
}
Code language: Go (go)
Notice that there is a comma (,
) after the line Age: 30
.
Put it all together:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
p := Person{
Name: "Joe",
Age: 30,
}
fmt.Printf("%+v\n", p)
}
Code language: Go (go)
Output:
{Name:Joe Age:30}
Code language: Go (go)
Accessing struct fields
To access a field of a struct, you use the dot notation:
structVariable.field
Code language: Go (go)
For example, to access the Name
and Age
fields of the Person
struct, you use p.Name
and p.Age
:
p := Person{
Name: "Joe",
Age: 30,
}
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
Code language: Go (go)
Output:
Name: Joe
Age: 30
Code language: Go (go)
Modifying struct fields
To modify a field in a string, you assign a new value to that field using the dot notation. For example, the following increases the Age
field value by one:
p := Person{
Name: "Joe",
Age: 30,
}
p.Age += 1
fmt.Println("Age:", p.Age)
Code language: Go (go)
Output:
Age: 31
Code language: Go (go)
Nested structs
Go allows a struct to be nested within another struct to create a complex data structure. For example:
package main
import "fmt"
type Address struct {
City, State, ZipCode string
}
type Person struct {
Name string
Age int
Address Address
}
func main() {
p := Person{
Name: "Joe",
Age: 30,
Address: Address{
City: "New York",
State: "NY",
ZipCode: "10001",
},
}
fmt.Printf("%+v", p)
}
Code language: Go (go)
How it works.
First, define a struct Address
that includes three string fields City
, State
, and ZipCode
:
type Address struct {
City, State, ZipCode string
}
Code language: Go (go)
Since three fields have the same type, you can specify them in a single declaration.
Second, define the Person
struct that has three fields Name
, Age
, and Address
. The type of the Address
field is the Address
struct:
type Person struct {
Name string
Age int
Address Address
}
Code language: Go (go)
Third, declare and initialize a Person
struct inside the main()
function and print it out:
func main() {
p := Person{
Name: "Joe",
Age: 30,
Address: Address{
City: "New York",
State: "NY",
ZipCode: "10001",
},
}
fmt.Printf("%+v", p)
}
Code language: Go (go)
Output:
{Name:Joe Age:30 Address:{City:New York State:NY ZipCode:10001}}
Code language: Go (go)
Passing a struct to a function
The following program attempts to pass a struct instance to a function and change the field value within the function.
package main
type Person struct {
Name string
Age int
}
func IncreaseAge(p Person) {
p.Age += 1
}
func main() {
p := Person{
Name: "Joe",
Age: 30,
}
IncreaseAge(p)
println(p.Age) // 30
}
Code language: Go (go)
How it works.
First, define the struct Person
with two fields Name
and Age
:
type Person struct {
Name string
Age int
}
Code language: Go (go)
Next, define the IncreaseAge
function that accepts a Person
struct instance. Inside the IncreaseAge
function, increase the Age
field value by one:
func IncreaseAge(p Person) {
p.Age += 1
}
Code language: Go (go)
Then, declare and initialize a struct variable inside the main()
function:
p := Person{Name: "Joe", Age: 30}
Code language: Go (go)
After that, pass the struct instance to the IncreaseAge
variable:
IncreaseAge(p)
Code language: Go (go)
Finally, display the Age
value:
println(p.Age)
Code language: Go (go)
The value of Age
field doesn’t change outside of the IncreaseAge
function. This is because Go passes a struct to the IncreaseAge
function by value.
This means Go makes a copy of the p
struct and changes the Age
on the copied version. Therefore, the change is not reflected outside the IncreaseAge
function.
To fix this issue, you need to use a pointer. Instead of passing a struct instance to the IncreaseAge
function, you can pass a pointer that points to the struct instance:
package main
type Person struct {
Name string
Age int
}
func IncreaseAge(p *Person) {
(*p).Age += 1
}
func main() {
p := Person{Name: "Joe", Age: 30}
IncreaseAge(&p)
println(p.Age)
}
Code language: Go (go)
Output:
31
Code language: Go (go)
How it works.
First, change the struct instance in the increaseAge()
function to a pointer of type Person
struct:
func IncreaseAge(p *Person) {
(*p).Age += 1
}
Code language: Go (go)
Inside the IncreaseAge
function, add one to the Age
field via the pointer.
Second, pass a pointer to the p
variable to the increaseAge
function in the main()
function:
IncreaseAge(&p)
Code language: Go (go)
Summary
- A struct is a composite type that includes multiple fields, which can have different types.
- To define a struct, use the type keyword followed by the struct name, struct keyword, and a list of fields.
- Use dot notation to access and modify fields.
- A struct can also be nested within another struct.