Go struct
A structure or struct in Golang is a user-defined type that allows to group set of related data together into a single type.
For example, you might want to consider a Point
as a structure that contains an x
and a y
coordinate or a Person
as a structure that contains a name
, an age
, and a list of friends
.
Declaring a structure
A structure is declared using the type
keyword and has the following general form:
type name struct {
field1 type1
field2 type2
// etc.
}
where name
is the name of the structure, field1
and field2
are the names of the fields and type1
and type2
are the associated types.
Basic examples
Let's write a structure for the two examples above:
type Point struct {
x float64
y float64
}
that can be used as follows:
p := Point{1.0, 2.0}
fmt.Println(p.x, p.y)
and
type Person struct {
name string
age int
friends []Person
}
that can be used as follows:
package main
import "fmt"
func main() {
type Person struct {
name string
age int
friends []Person
}
john := Person{"John", 20, []Person{}}
marc := Person{"Marc", 21, []Person{john}}
paul := Person{"Paul", 22, []Person{john, marc}}
fmt.Println(paul)
fmt.Println(paul.friends[0].name)
}
Output
{Paul 22 [{John 20 []} {Marc 21 [{John 20 []}]}]}
John
This last example shows that a field can be a structure itself. It should remind you of recursive functions (such as the factorial function).
Accessing the properties in Struct
We can access the struct field/properties using its instances. For Example:
package main
import "fmt"
func main() {
type Person struct {
name string
age int
}
// create an instance of Person
employee := Person{"John", 20}
fmt.Println("Name:", employee.name)
fmt.Println("Age:", employee.age)
}
Output
Name: John
Age: 20
Here, we have created a struct of type Person
, and it has two fields, name
and age
. Later we created an instance of struct with an object john
.
Using the dot notation (.), we can now access the fields of the struct.
Functions taking or returning a structure
A function can take a structure as a parameter or return a structure as a result. For example, we can write a function that returns the distance between two points:
func distance(p1, p2 Point) float64 {
return math.Sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y))
}
Note: the math
package should be imported.
Or we might compute the number of friends of a person:
func nbFriends(p Person) int {
return len(p.friends)
}
But a function might also return a structure.
func translate(p Point, dx, dy float64) Point {
return Point{p.x + dx, p.y + dy}
}
In this version of the translate
function, we create a new Point
structure and return it.
But sometimes, we might want to modify the structure in place.
Pointers to structures
In order to mutate a structure, we need to pass a pointer to it rather than letting the function create a copy of it.
func translate(p *Point, dx, dy float64) {
p.x += dx
p.y += dy
}
and it is used as follows:
p := Point{1.0, 2.0}
translate(&p, 3.0, 4.0)
fmt.Println(p.x, p.y)
The only difference in the syntax is the *
before the type of the parameter and the &
before the variable name when calling the function.