go - 为什么函数执行后值会发生变化?

标签 go

我目前正在自学围棋,但我无法理解某种行为:

package main

import (
    "fmt"
)

type List struct {
    n int
}

func (l List) Increment() {
    l.n += 1
    l.LogState() // size: 1
}

func (l List) LogState() {
    fmt.Printf("size: %v\n", l.n)
}

func main() {
    list := List{}
    list.Increment()

    fmt.Println("----")
    list.LogState() // size: 0
}

https://play.golang.org/p/-O24DiNPkxx

LogState 被执行了两次。最初,在 Increment 调用期间,它打印 size: 1 但在 Increment 返回后它打印 size: 0。为什么这些值不同?

最佳答案

您的节点未添加到原始 linkedList 的原因是您没有使用指向该结构的指针。因此,即使示例代码中的 Increment 函数更改了值。更改的是结构的副本,而不是实际的结构。

You can declare methods with pointer receivers. This means the receiver type has the literal syntax *T for some type T. (Also, T cannot itself be a pointer such as *int.)

如果您想更改 linkedlistNode 结构计数器以显示添加到列表中的节点,您应该在两种方法上使用指针类型接收器来修改链表:

func (l *LinkedList) AddInitialValue(v interface{})
func (l *LinkedList) LogState()

并且在 main 内部将一个地址传递给 linkedList 以将这些指针类型接收器用作:

func main() {
    list :=  &LinkedList{}
    list.AddInitialValue(9)

    fmt.Println("----")
    list.LogState() // size: 0
}

工作代码 Go playground

注意:-

使用指针接收器有两个原因。

  • To modify the value that its receiver points to.
  • To avoid copying the value on each method call. This can be more efficient if the receiver is a large struct

有关更多信息,请访问 Method Sets

关于go - 为什么函数执行后值会发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52799886/

相关文章:

go - pubsub.NewClient 方法卡在 GKE golang 上

JSON Unmarshal 不规则的 JSON 字段

regex - 如何匹配单词之间的短语

postgresql - Postgres : Optimising concurrent same row updates

mongodb - 如何使用mongodb/mongo-go-driver进行高效分页

Json 文件语法验证

git - 将 gitea 绑定(bind)到 localhost 地址以进行隧道传输?

go - 如何编写一个采用 go 中多种类型之一的函数?

用于谷歌云存储的 Golang SDK : Multipart download

go - 除了可移植性和安全性原因之外,为什么有人想通过 WebAssembly 在 Web 浏览器中运行他们现有的 go/rust/c++ 应用程序?