en

Go Pointers

27 May 2020 | 2mins

A pointer holds the memory address of a value. Used to reference and indirectly affect value.

Use ‘&’ to set the memory address of a pointer, and the ‘*’ operator to access (read or write) the value of a memory address through a pointer.

Ex: p is a pointer, n is not

   
    func main() {
      i, j := 42, 15
      var n int
      
      p := &i         // point to i
      fmt.Println(*p) // read i through the pointer
      *p = 21         // set i through the pointer
      fmt.Println(i)  // see the new value of i

      n = j    
      n = n / 5   
      fmt.Println(j)
      fmt.Println(n)
    }
    // $ 42
    // $ 21
    // $ 15
    // $ 3
   

OBS: Is possible to read the memory address of a value using the & operator.

   
    func main() {
      luckyNumber := 7

      fmt.Println(&luckyNumber)
    }
    // $ 0xc00002c008
   

Method Receiver

Methods vs Functions

In OOP a method is a function on an instance of an object. In go, we can declare methods on structs.

The method receiver is the type/struct that will be able to receive a specific method call. It is declared between de func keyword and the function name.

Example

   
    type User struct {
      FirstName, LastName string
    }

    func main() {
      u := User{"Roberto", "Barros"}

      fmt.Println(u.Greeting())
    }

    func (u User) Greeting() string {
      return fmt.Sprintf("Dear %s %s", u.FirstName, u.LastName)
    }

    // $ Dear Roberto Barros
   

Pointer Receiver

Methods can be declared on a value type(User), or on a pointer to a value type(*User).

As Go passes everything by value, if you declare the method on a value(as the above exemple), the struct will be copyed on every method call(Greeting).

If you declare a method on a pointer, only the pointer will be copyed on the method call, which is cheap.

   
    ...

    func main() {
      u := &User{"Roberto", "Barros"}

      fmt.Println(u.Greeting())
    }

    func (u *User) Greeting() string {
      return fmt.Sprintf("Dear %s %s", u.FirstName, u.LastName)
    }

    // $ Dear Roberto Barros
   

Another reason to assign a method to a pointer, is that the method can then modify the value that its receiver points to.

   
    ...

    func main() {
      u := &User{"Roberto", "Barros"}
      u.updateFirstName("Carlos")

      fmt.Println(u.FirstName)
    }

    func (u *User) updateFirstName(newFirstName string) {
      u.FirstName = newFirstName
    }

    // $ Carlos
   

OBS: Functions with pointers receivers(*User) can be called on a value of the same type(User). This is a Go shortcut.

Source

https://tour.golang.org/moretypes/1 http://www.golangbootcamp.com/book/methods

Hey, thanks for reading :D ! Any thoughts on this topic? Comment below! ;)