-3
package main
import "fmt"

type rabbit struct {
    food string
}

func (r *rabbit) change_food() {
    (*r).food = "salad"
}

func main() {
    var roger rabbit = rabbit{food: "carrot"}
    (&roger).change_food()
    fmt.Println(roger) //output --> salad

}

code above works, but I'd like to save (in the pointer receiver) the pointer dereference in a variable instead of writing every time (*r) without using shorthand because in my opinion with pointer receivers they are unclear/confusing. I prefer explicit dereference for cleaner code https://tour.golang.org/moretypes/4.

I tried this code:

package main

import "fmt"

type rabbit struct {
    food string
}

func (r *rabbit) change_food() {
    deref := *r //deref := (*r); var deref rabbit = (*r) also don't work
    deref.food = "salad"
}

func main() {
    var roger rabbit = rabbit{food: "carrot"}
    (&roger).change_food()
    fmt.Println(roger) //output --> carrot. I wanted salad

}

to mkopriva: I'd like to not use (*r) form, like for example I did with memory address now:

package main

import "fmt"

type rabbit struct {
    food string
}

func (r *rabbit) change_food() {
    (*r).food = "salad"
}

func main() {
    var roger rabbit = rabbit{food: "carrot"}
    var p *rabbit = &roger
    p.change_food() //before It was (&roger).change_food(), now code is cleaner
    fmt.Println(roger) //output --> salad

}
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/235568/discussion-on-question-by-user16570868-unable-to-save-pointer-dereference-in-poi). – Machavity Aug 03 '21 at 01:22

1 Answers1

0

Go automatically converts to and from pointers, both when calling methods, and when accessing attributes:

package main

import "fmt"

type rabbit struct {
    food string
}

func (r *rabbit) change_food() {
    r.food = "salad"
}

func main() {
    var roger = rabbit{food: "carrot"}
    roger.change_food()
    fmt.Println(roger)
}

change_food receiver takes a pointer, so even though roger is not a pointer, Go handles that automatically.

Similarly, even though food is an attribute of a rabbit, not a *rabbit, Go figures this out hand handles things properly.

You can't dereference a pointer and then change the data at the address of that pointer. That's why pointers exist - so you can change the underlying data instead of passing a copy.

If it's just a question of a naming convention, you could always define the receiver's variable name with a p:

func (rp *rabbit) change_food() {
   ...

But it's not common in Go languages to denote pointer types like this, perhaps because Go is a lot smarter at typing than something like C, and it doesn't really get confusing between pointers and values.

erik258
  • 14,701
  • 2
  • 25
  • 31
  • ty very much y'all, now it's more clear. One question: when I have to call a point receiver method, should I pass the pointer (ie (&variable).method() ) or the variable ( ie variable.method() ) . What are the different case of usage? – user16570868 Aug 02 '21 at 17:06
  • 1
    `(&variable).method` is always unnecessary. There's no reason I can think of to do it. – erik258 Aug 02 '21 at 18:06
  • https://youtu.be/CWPwF5Ocaf4?t=1003 check out this video: he is "forced" to pass the memory address since he was using pointer receiver – user16570868 Aug 02 '21 at 20:06
  • 1
    he's not calling a method or accessing an attribute in that example. He's passing a struct whose pointer (but not the struct itself) implements an interface. See https://stackoverflow.com/questions/40823315/x-does-not-implement-y-method-has-a-pointer-receiver – erik258 Aug 02 '21 at 20:21