Structs in Go are one of the most powerful and widely used features. They allow you to group related data together, making your code cleaner and more organized. In this blog, we’ll explore how to use structs, anonymous structs, and embedded structs with easy-to-understand examples.
What is a Struct in Go?
A struct is like a container that holds multiple pieces of related data together. For example, if you want to represent a car, you might want to include details like its model, the radius of its wheels, and the material of the wheels. A struct can group these details together.
Here’s a simple example of a struct:
type Wheel struct {
radius int
material string
}
type Car struct {
Model string
Wheel Wheel
}
Wheel
is a struct that hasradius
andmaterial
.Car
is a struct that has aModel
and aWheel
(which itself is a struct).
How to Use Structs?
To use a struct, you need to create an instance of it and provide values for its fields. Let’s look at an example:
car := Car{
Model: "BMW",
Wheel: Wheel{
radius: 4,
material: "Fibre",
},
}
fmt.Println(car)
Output:
{BMW {4 Fibre}}
Here, we:
- Created a
Car
instance namedcar
. - Gave it a
Model
value of"BMW"
. - Set the
Wheel
withradius
as4
andmaterial
as"Fibre"
.
What is an Anonymous Struct?
An anonymous struct is a struct without a name. You can define it directly inside another struct or inline where needed.
Here’s an example of an anonymous struct inside another struct:
type AnonymousCar struct {
Model string
Wheel struct { // Anonymous struct
radius int
material string
}
}
To initialize it:
anonymousCar := AnonymousCar{
Model: "BMW",
Wheel: struct {
radius int
material string
}{
radius: 5,
material: "Fibre2",
},
}
fmt.Println(anonymousCar)
Output:
{BMW {5 Fibre2}}
Notice that for the Wheel
field, we had to explicitly define the anonymous struct again when initializing it.
What is an Embedded Struct?
An embedded struct is a struct included directly in another struct. It allows you to use its fields as if they belong to the outer struct, making your code simpler.
Here’s an example:
type EmbeddedCar struct {
Model string
Wheel // Embedded struct
}
You can initialize it like this:
embeddedCar := EmbeddedCar{
Model: "BMW",
Wheel: Wheel{
radius: 6,
material: "Fibre2",
},
}
fmt.Println(embeddedCar)
Output:
{BMW {6 Fibre2}}
How is an Embedded Struct Different?
In an embedded struct:
- The fields of the inner struct (
Wheel
) become part of the outer struct (EmbeddedCar
). - You can access these fields directly:
fmt.Println(embeddedCar.radius) // Outputs: 6
fmt.Println(embeddedCar.material) // Outputs: Fibre2
This is more convenient than using an anonymous struct or nesting structs without embedding.
Complete Example Code
Here’s the full code combining all the concepts we discussed:
package main
import "fmt"
type Wheel struct {
radius int
material string
}
type Car struct {
Model string
Wheel Wheel
}
type AnonymousCar struct {
Model string
Wheel struct {
radius int
material string
}
}
type EmbeddedCar struct {
Model string
Wheel
}
func main() {
car := Car{
Model: "BMW",
Wheel: Wheel{
radius: 4,
material: "Fibre",
},
}
anonymousCar := AnonymousCar{
Model: "BMW",
Wheel: struct {
radius int
material string
}{
radius: 5,
material: "Fibre2",
},
}
embeddedCar := EmbeddedCar{
Model: "BMW",
Wheel: Wheel{
radius: 6,
material: "Fibre2",
},
}
fmt.Println(car)
fmt.Println(anonymousCar)
fmt.Println(embeddedCar)
}
Output:
{BMW {4 Fibre}}
{BMW {5 Fibre2}}
{BMW {6 Fibre2}}
Key Takeaways for Beginners
- Named Structs: Use them when you have reusable types (like
Wheel
). - Anonymous Structs: Use them when you need temporary or one-time-use types.
- Embedded Structs: Use them to simplify access to inner struct fields and avoid repetitive code.
By mastering these concepts, you can write cleaner and more organized code in Go!