Go语言 将指针设置为nil时,结构指针字段不改变

rdrgkggo  于 2022-12-07  发布在  Go
关注(0)|答案(2)|浏览(156)

我有这样的代码:

type X struct {
    y *X
}

func main() {
    x1 := &X{y: nil}
    x2 := &X{y: x1}

    fmt.Println(x1 == x2.y)
    // true

    x1 = nil

    fmt.Println(x1 == nil)
    fmt.Println(x2.y == nil)

    // true
    // false
}

正如你所看到的x.y是一个*X
为什么将x1设置为nil后,x2.y的值不会变为nil
如果我的问题太傻了,对不起。
下面是Go语言中代码的link

ivqmmu1c

ivqmmu1c1#

x1是指向X类型的{y:nil}的指针。x2.y也是指向同一个{y:nil的指针}。因此,当您设置x1=nil时,x1将成为一个为空的指针,而x2.y仍指向同一个{y:nil}对象。

3pmvbmvn

3pmvbmvn2#

不,x2.y仍然会指向您分配给x1的对象。这是您的代码的基本功能:

Objects in memory
| memory address | value             | 
| 0xDEADBEEF     | X{y: nil }        |
| 0x1BADB002     | X{y: 0xDEADBEEF } |
|----------------|-------------------|

In your code:
| variable     | value      |
| x1           | 0xDEADBEEF |
| x2           | 0x1BADB002 |

所以现在通过执行x1 = nil,你所做的就是改变一个变量的值:

| variable     | value      |
| x1           | nil        |
| x2           | 0x1BADB002 |

x2仍然指向内存中的一个值,而这个值又指向内存中的另一个对象,go运行时会识别出这一点,并发现存储在0xDEADBEEF中的对象仍在使用中,所以它不会释放内存。
更直观的表示形式如下所示:

+-----------+(0xDEADBEEF)
| X{y: nil} |
+-----------+
  /\       /\
  ||-------||--> Both point to the same object
 +----+    ||
 | x1 |    ||
 +----+    ||
+----------||------+(0x1BADB002)
| X{y: 0xDEADBEEF} |
+------------------+
  /\
  || points to this object
 +----+
 | x2 |
 +----+

通过设置x1 = nil,我们所做的只是切断了变量x1和内存中实际对象之间的链接,而x2.y和该对象之间的链接仍然存在。

相关问题