Golang Structs - A Deep Dive
Introduction
In Go, a struct is a fundamental building block of the language as it is used to represent a collection of data. Struct fields can be of any type, including other structs, and can have methods. In this article, we explore details of how to use them in your Go programs.
Defining a Struct
Structs are defined using the type
keyword and the struct
keyword.
Let’s define a struct that represents a person.
Initializing a Struct
Initializing an Empty Struct
Structs can be created in two ways. The first way is to use the new
keyword.
The second way is to use the &
operator.
Both of these methods will create a pointer to a struct. The new
keyword is a built-in function that allocates memory for a struct and returns a pointer to it. The &
operator is a shorthand for creating a pointer to a struct. Learn more about new here
Initializing a Struct with Values
To initialize a struct with values, we can use the &
operator.
We can also initialize without using the &
operator.
Accessing Struct Fields
Struct fields are accessed using the .
operator.
Since p
is a pointer to a struct, we can also use the pointer dereference operator *
to access the fields.
This will only work when you use the &
operator or new
keyword to initialize the struct.
Struct Methods
Structs can have methods defined on them. These methods are similar to functions, but are defined on a struct and are used to encapsulate any logic related to the struct.
The fullName
method is defined on the Person
struct and can access the fields of the the struct using the p
parameter. The fullName
method can then be called on a Person
struct.
Pointer Receivers vs Value Receivers
When defining a method on a struct, we can use either a pointer receiver or a value receiver.
Pointer Receiver - Mutates the struct
A pointer receiver is defined by using the *
operator in the method definition. Pointer receivers are useful when we want to modify the fields of the struct.
Value Receiver - Does not mutate the struct
On the other hand, a value receiver is defined by using the struct name only in the method definition. They are useful when we want to create a copy of the struct and modify the copy or just read the fields of the struct.
The p.Age++
line will not modify the Age
field of the struct. If you try to access the Age
field of the struct outside of the method, you will see that it has not been modified.
Struct Embedding
Structs like interfaces can be embedded into other structs. This is useful when we want to reuse the fields and methods of a struct in another struct. This introduces the concept of composition in Go.
In this example, the Employee
struct embeds the Person
struct. Meaning that the Employee
struct has access to the fields and methods of the Person
struct.
Since the Employee
struct embeds the Person
struct, we can access the fields of the Person
struct using the .
operator.
We can also access the fields of the Person
struct using the Person
field.
Struct Tags
Struct tags are metadata that can be attached to struct fields to provide additional information about the field. Struct tags are defined using backticks.
Struct tags can be accessed using the reflect
package.
Struct tags are commonly used with JSON encoding and decoding as they provide additional information about the fields of a struct. Learn more about JSON encoding and decoding in Go here
Conclusion
In this article, we learned about structs in Go. Here are some key takeaways:
- Structs are used to represent a collection of related data.
- Structs can be initialized using the
new
keyword or the&
operator. - Struct fields are accessed using the
.
operator. - Structs can have methods defined on them.
- Structs can be embedded into other structs.
- Struct tags are metadata that can be attached to struct fields.