-4

How come this program prints nil instead of hello? How can I solve this situation and successfully store that pointer in the struct? Shouldn't Go be able to figure out when local pointers are used outside the scope of a function?

package main

import (
    "fmt"
)

type test struct {
    name *string
}

func (t test) test() {
    h := "hello"
    t.name = &h
    return
}

func main() {
    a := test{nil}
    a.test()
    fmt.Println(a.name)
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • 2
    `func (t test) test()` is a value receiver on `test`. This means that the method is called on a copy of `a`. That copy has `t.name` set during the function call, but there is nothing to copy it back to `a`. Use a pointer receiver instead: `func (t *test) test()`. – Marc Jul 02 '20 at 13:43

1 Answers1

2

Your test function has a value receiver. So test will be applied on a copy of a. If you want to mutate a struct with a method, you should write a method which has a pointer receiver. On calling the method, go will automatically use the reference for this method

func (t *test) test() {
    h := "hello"
    t.name = &h
}
poWar
  • 745
  • 6
  • 15
  • Are pointer receivers always recommended for speed, or for read-only methods value receivers are better suited? – user13853590 Jul 02 '20 at 13:55
  • If you have to mutate a struct in a method, go with a pointer receiver. Else stick to a value receiver. Speed will be dependant on how the code works on the hardware. You can write a simple benchmark to see how it changes for both the methods. – poWar Jul 02 '20 at 14:12
  • Also check [this](https://stackoverflow.com/questions/27775376/value-receiver-vs-pointer-receiver) which covers the point you raised. – poWar Jul 02 '20 at 14:16
  • Correction: Else stick to a value receiver unless your struct is massive (You do not want copies of massive structs to be created unnecessarily) – poWar Jul 02 '20 at 14:18