代码之家  ›  专栏  ›  技术社区  ›  bjnsn

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

go
  •  1
  • bjnsn  · 技术社区  · 6 年前

    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 但之后呢 增量 已经归还了指纹 size: 0 . 为什么这些价值观不同?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Himanshu    6 年前

    节点未添加到原始linkedList的原因是您没有使用指向结构的指针。所以即使 Increment 函数更改值。结构的副本被更改,而不是实际的结构。

    对于某些类型T,receiver type具有文本语法*T(还有,T 本身不能是诸如*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

    Note:-

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

    • 修改其接收器指向的值。

    更多信息请浏览 Method Sets

        2
  •  1
  •   Emin Laletovic    6 年前

    Increment LogState 复制 List . 这意味着如果你在里面做些改变 增量 功能,它们只在内部可见 值,您可以记录 &list 执行前 增量 功能和 &l

    如果要使更改永久化,应该使用指向内存地址的指针。这意味着函数的定义如下:

    func (l *List) Increment()
    
    func (l *List) LogState()
    

    这样,您就可以传递一个内存引用(指向内存中地址的指针),并且每次更改 l ,您在传递的内存引用上更改它,它会反映到所有地方。