首页 > 解决方案 > 无法在指针接收器结构 golang OOP 中保存指针取消引用

问题描述

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

}

上面的代码有效,但我想(在指针接收器中)将指针取消引用保存在变量中,而不是每次都写入(*r)而不使用速记,因为在我看来,指针接收器不清楚/令人困惑。我更喜欢明确取消引用更清晰的代码https://tour.golang.org/moretypes/4

我试过这段代码:

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

}

对 mkopriva: 我不想使用 (*r) 形式,例如我现在使用内存地址:

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

}

标签: oopgopointers

解决方案


在调用方法和访问属性时, Go会自动与指针相互转换:

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接收者接受一个指针,因此即使roger不是指针,Go 也会自动处理它。

类似地,即使food是 a 的一个属性rabbit,而不是 a *rabbit,Go 也认为它可以正确处理事情。

您不能取消引用指针,然后更改该指针地址处的数据。这就是存在指针的原因——因此您可以更改基础数据而不是传递副本。

如果这只是一个命名约定的问题,你总是可以用 a 定义接收者的变量名p

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

但是在 Go 语言中这样表示指针类型并不常见,这可能是因为 Go 在打字方面比 C 更聪明,而且它不会真正混淆指针和值。


推荐阅读