go - 在 golang 中,如何从函数内重新分配外部引用?

标签 go

我可能没有在问题中正确表达这一点,但也许这段代码会让它更清楚:

package main
import "fmt"

type Blob struct {
    Message string
}

func assign1(bb **Blob) {
    *bb = &Blob{"Internally created by assign1"}
}

func (b *Blob) assign2() {
    *b = Blob{"Internally created by assign2"}
}

func main() {
    x1 := &Blob{"Hello World"}
    assign1(&x1)
    fmt.Printf("x1 = %+v\n", *x1)

    x2 := Blob{"Hello World"}
    x2.assign2()
    fmt.Printf("x2 = %+v\n", x2)
}

根据需要生成:

x1 = {Message:Internally created by assign1}
x2 = {Message:Internally created by assign2}

我想将一个引用(指向一个指针的指针)传递给一个函数,并让该函数为该指针分配一个新值,以便调用范围将看到该新值。

我已经想出了以上两种方法,但我想知道它们是否真的正确,或者是否存在一些隐藏的缺陷。另外,他们中的任何一个比另一个更地道吗?

来自 Java,assign2 似乎是错误的,但我确信我在 encoding/json 包中看到过类似的东西。它到底在做什么?

谢谢!

最佳答案

James answers assign2 的机制。我会稍微介绍一下何时使用它。

让我们先举一个更简单的例子。

type Counter uint

func (c *Counter) Increment() {
    *c += 1
}

在反例中,接收器的整个 状态正在改变。类似地,对于 encoding/json 包,接收器的整个 状态正在改变。那真的是我唯一一次使用这种风格。

该样式的一个主要优点:您可以为更改定义一个接口(interface),就像 GobDecoder

当我第一次看到 assign2 样式时,它有点刺耳。但后来我想起 (c *Counter) Increment 在机器代码中被翻译成 Increment(c *Counter) 并且它不再困扰我了。我个人更喜欢 assign1 风格。 (不过,对于最初发布的双指针,有 no need。)

package main
import "fmt"

type Blob struct {
    Message string
}

func assign1(b *Blob) {
    *b = Blob{"Internally created by assign1"}
}

func main() {
    x1 := Blob{"Hello World"}
    assign1(&x1)
    fmt.Printf("x1 = %+v\n", *x1)
}

关于go - 在 golang 中,如何从函数内重新分配外部引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28825259/

相关文章:

go - 如何在运行 go mod download 时强制使用特定的软件包版本?

go - 如何在 golang CLI 中在远程机器上执行命令?

go - yaml:解码错误:无法将字符串解码为时间。Golang 中的持续时间

go - 如何通过 exec os/exec 执行 sc create 命令?

slice 接口(interface)上的 Golang Switch Case

java - 使用 Golang 中的类路径和库路径运行 Java 命令

windows - Golang : HTTP deployment under Windows

go - 如何检查接口(interface){}是否是一个 slice

go - 在 Go 中使用 UDP 的客户端/服务器

go - 关于打高尔夫球,有没有一种好方法可以避免此代码中出现冗余?