Go 整数和字符串是不可变的还是可变的?

Go Ints and Strings are immutable OR mutable?

我在互联网上读到的关于整数和字符串的内容是它们本质上是不可变的。 但是下面的代码表明,在改变这些类型的值之后,它们仍然指向同一个地址。这与 python 中类型本质背后的想法相矛盾。 谁能解释一下这个? 提前致谢。

package main

import (
    "fmt"
)

func main() {
    num := 2
    fmt.Println(&num)
    num = 3
    fmt.Println(&num) // address value of the num does not change

    str := "2"
    fmt.Println(&str)
    str = "34"
    fmt.Println(&str) // address value of the str does not change

}```

当你读到一个字符串是不可变的,这意味着你不能通过索引修改它,例如:

x := "hello"
x[2] = 'r'
//will raise an error

正如评论所说,当你修改整个var(而不是它的一部分带有索引)时,它与是否可变无关,你可以这样做

数字本质上是不可变的。 7是7,明天不是8。这并不意味着存储在变量中的 哪个 数字不能更改。变量变量。它们是可变或不可变值的可变容器。

Go 字符串在语言设计上是不可变的; string 类型不支持任何可变运算符(例如在字符串中间附加或替换字符)。但是,同样,赋值可以改变变量包含的哪个字符串。

在Python(至少CPython)中,数字被实现为一种对象,像任何其他对象一样具有地址和字段。当您使用 id() 进行技巧操作时,您正在查看变量“背后”的对象地址,该地址可能会或可能不会更改,具体取决于您对它所做的操作,以及它是否最初是一个 interned小整数或类似的东西。

在围棋中,整数就是整数。它存储为一个整数。变量的地址就是变量的地址。如果垃圾收集器决定移动它,变量的地址可能会改变(使地址的数值或多或少无用),但它不会向您揭示任何关于算术运算符实现的技巧,因为没有'没有。

字符串比整数更复杂;他们在内部有点object-ish,是structure containing a pointer and a size。但是用 &str 获取字符串变量的地址并不能告诉你关于该内部结构的任何信息,也不能告诉你 Go 编译器是否决定使用 de novo 赋值的字符串值,或者就地修改旧的(它可以在不违反任何规则的情况下,如果它能证明旧的永远不会被其他任何东西再次看到)。它只告诉您 str 的地址。如果您想查明该内部指针是否已更改,您将不得不使用反射...但几乎没有任何实际理由这样做。