为什么改变指针的副本不影响初始对象?

问题描述 投票:1回答:1

我学会了处理指针,在这个例子中,我不明白为什么将i3分配给一个新的当前对象,并做动作current = current.next并不影响i3对象。但是,使用了相同的地址

func main() {

        i := &Node{data: 1}
        i2 := &Node{data: 2, next: i}
        i3 := &Node{data: 3, next: i2}

        current := i3
        for current.next != nil {
                current = current.next
        }
        log.Println(current)
        log.Println(i3)
        /*
        2020/06/03 12:19:23 &{1 <nil>}
        2020/06/03 12:19:23 &{3 0xc42000e1f0}
        */

}

type Node struct {
        data int 
        next *Node
} 

而如果我不使用i3对象的副本,该对象在循环中会被很好地修改。

func main() {

        i := &Node{data: 1}
        i2 := &Node{data: 2, next: i}
        i3 := &Node{data: 3, next: i2}

        log.Println(i3)
        /*
                2020/06/03 12:22:05 &{3 0xc42000e1f0}
        */
        for i3.next != nil {
                i3 = i3.next
        }
        log.Println(i3)
        /*
                2020/06/03 12:22:05 &{1 <nil>}
        */

}
pointers go
1个回答
2
投票

currenti3 都是指针。

current:= i3

复制一个指针意味着现在 current 将指向同一个地址 i3 点。

指针的复制与被复制的指针没有任何关系,只是两个指针的值相同。所以修改 current 没有任何影响 i3.

你可以使用这种方式

current := &i3
for (*current).next != nil {
    *current = (*current).next
}

现在 current 是一个指针 i3现在,如果你改变当前的指向值,将影响到 i3.


2
投票

在你的第一个例子中,短变量声明。

current := i3

创建一个新变量,名为 current 的指针类型。它是一个不同的变量,比 i3,但它有相同的指针值。

循环只修改(赋值给)这个 current 变量,所以存储在 i3 永不改变。所以在循环之后 i3 仍然指向具有 data = 3current 将是最后一个,那就是与 data = 1.

在你的第二个例子中,你没有创建一个 current 变量,但你修改了(分配给 i3 变量。所以在循环之后,它将指向最后一个带有 data = 1. 在这两种情况下,节点对象都不会被修改,只需修改 currenti3 变量。


1
投票

在第一个例子中,你创建了一个指针式的 current 它将具有相同的值 i3 有(结构体的地址 Node{data: 3, next: i2}).

当你执行 current = current.next 语句,你只改变指针的值,而不是地址后面的值。你只替换了指针中存储的地址。

如果你按照迭代。

0., current -> Node{data: 3, next: i2}     
1., current -> Node{data: 2, next: i}     
2., current -> Node{data: 1}  

其他指针将保持不变。

i -> Node{data: 1}      
i2 -> Node{data: 2, next: i}     
i3 -> Node{data: 3, next: i2}   

在第二种情况下,你做了非常相同的事情,但是代替了之前的 current 指针,现在你改变了存储在 i3 指针.如果你跟着迭代。

0., i3 -> Node{data: 3, next: i2}     
1., i3 -> Node{data: 2, next: i}     
2., i3 -> Node{data: 1}     

其他指针将保持不变.

i -> Node{data: 1}      
i2 -> Node{data: 2, next: i}  

当然,你会在内存的某个地方有一个对象,但却无法访问它(Node{data: 3, next: i2})。

© www.soinside.com 2019 - 2024. All rights reserved.