Go Pointers and Functions

Pointer as Function Argument in Golang

In Go, pointers are often used as function arguments to modify the value of a variable passed to a function. When you pass a variable to a function in Go, a copy of the variable is created and passed to the function. This means that if you modify the variable inside the function, the original variable outside the function is not changed.

However, if you pass a pointer to a variable to a function, the function can modify the value of the variable directly through the pointer. To pass a pointer as a function argument in Go, you simply declare the function parameter as a pointer type.

Here's an example that demonstrates how to pass a pointer as a function argument in Go:

refer to:‮i‬giftidea.com
func updateValue(p *int) {
    *p = 10
}

func main() {
    var x int = 5
    fmt.Println(x) // prints "5"
    
    updateValue(&x)
    fmt.Println(x) // prints "10"
}

In this example, the updateValue function takes a pointer to an integer value as its parameter. The function updates the value of the integer by dereferencing the pointer and setting its value to 10.

In the main function, an integer variable x is declared and initialized to 5. The updateValue function is then called with the address of x (&x) as its argument. This means that the p parameter in the updateValue function points to x. After the function call, the value of x is updated to 10.

Note that in Go, it is common to use the & operator to get the address of a variable when passing it as a pointer argument to a function. In the example above, updateValue(&x) passes a pointer to x to the updateValue function.

Using pointers as function arguments in Go can be a powerful tool for modifying values and avoiding unnecessary copying of data. However, it is important to use pointers carefully and ensure that you are not modifying memory that is being used elsewhere in your program.

Return Pointers From Function

In Go, you can return a pointer from a function just like any other type. When you return a pointer from a function, you are returning a reference to a value that exists outside of the function. This can be useful for avoiding unnecessary copying of data, or for returning values that are too large to be passed as a value.

Here's an example of a function that returns a pointer to an integer:

func getValue() *int {
    x := 10
    return &x
}

func main() {
    p := getValue()
    fmt.Println(*p) // prints "10"
}

In this example, the getValue function declares an integer variable x and initializes it to 10. The function then returns a pointer to x by using the & operator to get the address of the variable.

In the main function, the getValue function is called and its return value is assigned to a variable p. This variable is a pointer to an integer. To get the value of the integer, we use the * operator to dereference the pointer and get the value that it points to. The expression *p returns the value of the integer x, which is 10.

It's important to note that when you return a pointer from a function, you are returning a reference to a value that may no longer exist after the function returns. In the example above, the variable x is declared within the getValue function, so it will be destroyed when the function returns. Therefore, you should only return a pointer to a value that will continue to exist after the function returns.

Here's another example that demonstrates how to return a pointer to a struct:

type Person struct {
    name string
    age  int
}

func getPerson() *Person {
    p := Person{name: "John", age: 30}
    return &p
}

func main() {
    ptr := getPerson()
    fmt.Println(*ptr) // prints "{John 30}"
}

In this example, the getPerson function creates a new Person struct and initializes its fields. The function then returns a pointer to the Person struct using the & operator.

In the main function, the getPerson function is called and its return value is assigned to a pointer variable ptr. To access the fields of the Person struct, we use the * operator to dereference the pointer and get the struct value that it points to. The expression *ptr returns the Person struct with the fields name and age.

Call By Reference in Go

Go supports passing arguments to functions by reference through the use of pointers. When you pass a pointer to a function, you can modify the value of the original variable from inside the function.

Here's an example of a function that accepts a pointer to an integer:

func changeValue(p *int) {
    *p = 10
}

func main() {
    x := 5
    changeValue(&x)
    fmt.Println(x) // prints "10"
}

In this example, the changeValue function accepts a pointer to an integer. The function uses the * operator to dereference the pointer and set the value of the integer to 10.

In the main function, a new integer variable x is declared and initialized to 5. The changeValue function is called with a pointer to x using the & operator. This passes a reference to x to the changeValue function, allowing it to modify the value of x.

After the changeValue function returns, the value of x has been changed to 10, which is printed to the console using the fmt.Println function.

It's important to note that when you pass a pointer to a function, the function can modify the value of the original variable. This can be useful for avoiding unnecessary copying of data or for modifying values that are too large to be passed as a value.

However, you should be careful when using pointers to avoid unintended side effects or errors. If multiple functions have access to the same pointer, changes made in one function can affect the values in another function. It's also important to make sure that the pointer is pointing to a valid memory address to avoid crashes or undefined behavior.