Go 为什么函数执行后值会发生变化?
我目前正在自学围棋,我很难理解某个行为:Go 为什么函数执行后值会发生变化?,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 :=
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
}
LogState
执行两次。初始时间,在Increment
调用期间,它打印size:1
,但在Increment
返回后,它打印size:0
。为什么这些值不同?使用Increment
和LogState
定义它们的方式,您只能使用列表的值的副本。这意味着,如果在Increment
函数中进行某些更改,则这些更改仅在Increment
的函数范围内可见,并且仅在该特定范围的剩余部分可见。要确认始终使用初始列表
值的副本,可以在同一函数内执行增量
函数和&l
之前记录&List
如果要使更改永久化,则应使用指向内存地址的指针。这意味着您的函数应定义如下:
func (l *List) Increment()
func (l *List) LogState()
通过这种方式,您正在传递一个内存引用(指向内存中地址的指针),每次更改l
的值时,您都会在传递的内存引用上更改它,并且它会反映到所有地方。由于您没有使用指向结构的指针,所以节点未添加到原始linkedList的原因。因此,即使示例代码中的Increment
函数更改了值。结构的副本更改为实际结构
可以使用指针接收器声明方法。这意味着
对于某些类型T,receiver type具有文本语法*T。(同样,T
本身不能是一个指针,如*int.)
如果要更改linkedlistNode结构计数器以显示添加到列表中的节点,则应在两种方法上使用指针类型接收器,以将链接列表修改为:
func (l *LinkedList) AddInitialValue(v interface{})
func (l *LinkedList) LogState()
并在主目录中向linkedList传递一个地址,以将这些指针类型接收器用作:
func main() {
list := &LinkedList{}
list.AddInitialValue(9)
fmt.Println("----")
list.LogState() // size: 0
}
工作代码
注意:-
使用指针接收器有两个原因
- 修改其接收器指向的值李>
- 避免在每个方法调用上复制值。如果接收器是一个大的结构,这可能会更有效
有关更多信息,请查看的可能重复项,以及更多信息。