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

我在互联网上读到的关于整数和字符串的内容是它们本质上是不可变的。但是下面的代码表明,在改变这些类型的值之后,它们仍然指向同一个地址。这与 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


}```


慕标5832272
浏览 93回答 2
2回答

红颜莎娜

数字本质上是不可变的。7是7,明天不是8。这并不意味着存储在变量中的数字不能改变。变量是变量。它们是可变或不可变值的可变容器。根据语言设计,Go 字符串是不可变的;该string类型不支持任何可变运算符(例如在字符串中间附加或替换字符)。但是,同样,赋值可以改变变量包含的字符串。在 Python(至少是 CPython)中,数字被实现为一种对象,与任何其他对象一样具有地址和字段。当你用 做技巧时id(),你正在查看变量“后面”的对象的地址,它可能会改变也可能不会改变,这取决于你对它做了什么,以及它最初是否是一个 interned 小整数或类似的东西那。在 Go 中,整数就是整数。它存储为一个整数。变量的地址就是变量的地址。如果垃圾收集器决定移动它,变量的地址可能会改变(使地址的数值或多或少无用),但它不会向您揭示任何关于算术运算符实现的技巧,因为没有'没有。字符串比整数更复杂;它们在内部有点像对象,是一个包含指针和大小的结构。但是获取字符串变量的地址&str并不能告诉你关于该内部结构的任何信息,也不能告诉你 Go 编译器是否决定使用新的字符串值进行赋值,或者修改旧的地方(它可以,在不违反任何规则的情况下,如果它能证明旧的再也不会被其他任何东西看到)。它告诉你的只是 的地址str。如果您想查明该内部指针是否已更改,则必须使用反射……但几乎没有任何实际理由这样做。

交互式爱情

当你读到一个字符串是不可变的时,这意味着你不能通过索引修改它,例如:x := "hello"x[2] = 'r'//will raise an error正如评论所说,当您修改整个 var(而不是使用索引的一部分)时,它与是否可变无关,您可以这样做
打开App,查看更多内容
随时随地看视频慕课网APP