They play a crucial role in building the real-world applications as they allow us to represent the real-world entities as single unites.
One of the common tasks when working with structs in Go is copying them. No, we are not talking about copy and paste.
In this tutorial, we will learn about the workings of copying structs in Go. This includes struct literals, copying the fields, and more.
Golang Structs
Before we delve into struct copying, let us first understand the basics of structs in Go.
Defining a Struct
To define a struct in Go, we use the “type” keyword followed by a struct definition. An example of a struct is as follows:
ModelName string
Mileage int
Year int
}
In the given example, we define a struct called “Car” with three main fields: ModelName, Mileage, and Year.
Struct Instantiation
To create an instance of a struct, we can simply declare a variable of the struct type and initialize it using a struct literal.
For example:
ModelName: "Mercedes Benz GLS-250 (4Matic)",
Mileage: 299,
Year: 2029,
}
In this case, we create an instance of the struct called “c” and assign a value to each of the fields that pertains to that instance.
Accessing the Struct Fields
We can access the fields of a struct using the dot notation as shown in the following example code:
import "fmt"
type Car struct {
ModelName string
Mileage int
Year int
}
func main() {
c := Car{
ModelName: "Mercedes Benz GLS-250 (4Matic)",
Mileage: 299,
Year: 2029,
}
fmt.Println("Model Name:", c.ModelName)
fmt.Println("Mileage:", c.Mileage)
fmt.Println("Year:", c.Year)
}
Once we run the given code, it should print the fields and values of the struct instance as follows:
Mileage: 299
Year: 2029
Copy the Struct in Golang
With the basics of working with structs out of the way, let us proceed and learn about struct copying.
What Is Struct Copying?
Struct copying refers to the process of creating a new copy of an existing struct with a similar field value as the existing struct.
One common use case of struct copy is when we need to modify a struct that actually affects the original struct or when you need to pass a copy of a struct to a given function and avoid the cascading effects to the original struct.
Structs in Go are value types which means that when we assign a struct to a new variable or pass it to a function, a copy of the struct is created.
NOTE: In the concurrent programs, sharing a mutable data between goroutines can lead to race conditions. Copying the structs can help avoid the data races by ensuring that each goroutine has its own copy of the data.
Method 1: Using the Assignment Operator
The simplest and most common method of copying a strut is using the assignment operator (=).
As we mentioned, assigning a new variable to a struct creates a copy of the struct.
An example of using this technique is as follows:
c := Car{
ModelName: "Mercedes Benz GLS-250 (4Matic)",
Mileage: 299,
Year: 2029,
}
fmt.Println("Model Name:", c.ModelName)
fmt.Println("Mileage:", c.Mileage)
fmt.Println("Year:", c.Year)
copy := c
}
In this example, we simply assign the original struct (c) to a new variable.
Method 2: Using the Field-by-Field Copy Technique
The field-by-field copy involves us creating a new struct and manually copying each field from the original struct to the new one.
To demonstrate, consider the following example code:
c := Car{
ModelName: "Mercedes Benz GLS-250 (4Matic)",
Mileage: 299,
Year: 2029,
}
fmt.Println("Model Name:", c.ModelName)
fmt.Println("Mileage:", c.Mileage)
fmt.Println("Year:", c.Year)
copy := Car{
ModelName: c.ModelName,
Mileage: c.Mileage,
Year: c.Year,
}
}
In this case, we create a new struct called “copy” and assign the fields to the values of the original struct.
This technique is especially useful when we need a granular control over which fields to include.
Method 3: Using the Struct Literal
Another approach is to use a struct literal to create a copy of the original struct. This basically passes the original struct as the value to the new struct.
An example is as follows:
ModelName: "Mercedes Benz GLS-250 (4Matic)",
Mileage: 299,
Year: 2029,
}
copy := Car(c)
This should create a new copy of the original struct with the same field values.
One drawback of this method is that it tends to be less explicit. Use it wisely to avoid an unexpected behavior.
Method 4: Using the Reflect Package
We also have access to the “reflect” package which provides us to copy a struct using reflection.
An example is as follows:
copy := reflect.New(reflect.TypeOf(c)).Elem().Interface().(Car)
One disadvantage of this method is that it has performance overhead and potential complexity. It is flexible but not entirely the most efficient.
Conclusion
In this tutorial, we covered the basics of structs in Go. We also covered about struct copying, why you might need it, and explored all the methods and techniques of copying the structs in Go.