The Go programming language, also known as Golang, is widely used for its simplicity, efficiency and performance. One of Go's key features is the way it handles passing data to functions: some types of data are passed by value, while others are passed by reference. In this article, we'll explore the concepts of passing by value and passing by reference in Go and the data types associated with each mode.
Pass by value
In passing by value, a copy of the data is made and this copy is passed to the function. In other words, changes made to the copy inside the function will not affect the original variable outside the function. In Go, the following data types are passed by value:
Simple data types
Simple data types, such as integers (int), floats (float64), strings (string), and booleans (bool), are passed by value. This means that when you pass a variable of one of these types to a function, the function will receive a copy of the variable, not the reference to the original variable.
package main
import "fmt"
func editInt(int number) {
number = 42
}
func main() {
x := 10
editInt(x)
fmt.Println(x) // Print 10, since x is passed as value
}
Array
Arrays in Go are passed by value. Although they are more complex than int or string, when you pass an array to a function, it will receive a copy of the original array.
package main
import "fmt"
func editArray(arr [3]int) {
arr[0] = 42
}
func main() {
a := [3]int{1, 2, 3}
editArray(a)
fmt.Println(a) // Print [1 2 3], since the array is passed by value
}
Struct
Structs in Go are passed by value, just like arrays and other complex data types. When you pass a struct to a function, it receives a copy of the original struct.
package main
import "fmt"
type Person struct {
Name string
Email string
}
func editStruct(p Person) {
p.Name = "Mario"
p.Email = "mario@site.tld"
}
func main() {
personOriginale := Persona{"Luca", "luca@site.tld"}
editStruct(originalperson)
fmt.Println(originalperson) // Print {Luca luca@site.tld}, since the struct is passed by value
}
Pass by reference
In passing by reference, a pointer or reference is passed to the original variable. This means that any changes you make to the variable within the function will directly affect the original variable. In Go, the following data types are passed by reference:
Slice
Slices in Go are flexible data structures and are passed by reference. When you pass a slice to a function, the function receives a reference to the original slice.
package main
import "fmt"
func editSlice(slice []int) {
slice[0] = 42
}
func main() {
s := []int{1, 2, 3}
editSlice(s)
fmt.Println(s) // Print [42 2 3], since the slice is passed by reference
}
Map
Maps in Go are also passed by reference. When you pass a map to a function, it receives a reference to the original map.
package main
import "fmt"
func editMap(map map[string]int) {
map["key"] = 42
}
func main() {
m := map[string]int{"key": 1}
editMap(m)
fmt.Println(m) // Print map[key:42], since the map is passed by reference
}
Pointers
You can also explicitly pass a pointer to a variable in Go, allowing the caller and function to access and modify the same variable through the pointer.
package main
import "fmt"
func editWithPointer(p *int) {
*p = 42
}
func main() {
x := 10
editWithPointer(&x)
fmt.Println(x) // Print 42, because a pointer was passed
}
In conclusion, in Go the passing of data to functions can occur by value or by reference, depending on the type of data. Understanding the difference between passing by value and passing by reference is essential to writing effective Go code and avoiding unexpected behavior. Using this knowledge, you can select the appropriate step type for your data based on your programming needs.