Go中的整数(Ints)和字符串(Strings)是不可变的还是可变的?

huangapple go评论138阅读模式
英文:

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) // num的地址值没有改变

	str := "2"
	fmt.Println(&str)
	str = "34"
	fmt.Println(&str) // str的地址值没有改变

}```

<details>
<summary>英文:</summary>

What I am reading about ints and strings over internet is they are immutable in the nature.
But the following code shows that after changing the values of these types, still they points to the same address. This contradicts the idea behind the nature of types in python.
Can anyone please explain me this?
Thanks in advance. 

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 := &quot;2&quot;
fmt.Println(&amp;str)
str = &quot;34&quot;
fmt.Println(&amp;str) // address value of the str does not change

}```

答案1

得分: 6

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

在Go语言中,字符串是不可变的;string类型不支持任何改变操作(比如在字符串中间添加或替换字符)。但是,赋值操作可以改变变量所包含的字符串。

在Python中(至少在CPython中),数字被实现为一种对象,具有地址和字段,就像其他对象一样。当你使用id()进行操作时,你看到的是变量“后面”对象的地址,这取决于你对它做了什么,以及它最初是否是一个内部化的小整数或类似的东西,它的地址可能会改变或不改变。

在Go中,整数就是整数。它以整数的形式存储。变量的地址就是变量的地址。如果垃圾收集器决定移动它,变量的地址可能会改变(使地址的数值几乎没有用处),但它不会向你透露任何关于算术运算符实现的技巧,因为根本就没有这样的技巧。

字符串比整数更复杂;它们在内部是一种类似对象的结构,包含一个指针和一个大小。但是,使用&str获取字符串变量的地址并不能告诉你关于内部结构的任何信息,也不能告诉你Go编译器是否决定为赋值使用一个全新的字符串值,还是在原地修改旧值(如果它能证明旧值不会再被其他任何东西看到,那么它可以这样做,而不违反任何规则)。它只告诉你str的地址。如果你想找出内部指针是否改变,你需要使用反射...但实际上很少有实际的理由这样做。

英文:

A number is immutable by nature. 7 is 7, and it won't be 8 tomorrow. That doesn't mean that which number is stored in a variable cannot change. Variables are variable. They're mutable containers for values which may be mutable or immutable.

A Go string is immutable by language design; the string type doesn't support any mutating operators (like appending or replacing a character in the middle of the string). But, again, assignment can change which string a variable contains.

In Python (CPython at least), a number is implemented as a kind of object, with an address and fields like any other object. When you do tricks with id(), you're looking at the address of the object "behind" the variable, which may or may not change depending on what you do to it, and whether or not it was originally an interned small integer or something like that.

In Go, an integer is an integer. It's stored as an integer. The address of the variable is the address of the variable. The address of the variable might change if the garbage collector decides to move it (making the numeric value of the address more or less useless), but it doesn't reveal to you any tricks about the implementation of arithmetic operators, because there aren't any.

Strings are more complicated than integers; they are kind of object-ish internally, being a structure containing a pointer and a size. But taking the address of a string variable with &amp;str doesn't tell you anything about that internal structure, and it doesn't tell you whether the Go compiler decided to use a de novo string value for an assignment, or to modify the old one in place (which it could, without breaking any rules, if it could prove that the old one would never be seen again by anything else). All it tells you is the address of str. If you wanted to find out whether that internal pointer changed you would have to use reflection... but there's hardly ever any practical reason to do so.

答案2

得分: 1

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

x := "hello"
x[2] = 'r'
//会引发错误

正如一条注释所说,当你修改整个变量(而不是使用索引修改其中的一部分)时,这与是否可变无关,你是可以这样做的。

英文:

When you read about a string being immutable, it means you cannot modify it by index, ex:

x := &quot;hello&quot;
x[2] = &#39;r&#39;
//will raise an error

As a comment says, when you modify the whole var(and not a part of it with an index), it's not related to being mutable or not, and you can do it

huangapple
  • 本文由 发表于 2022年3月23日 23:23:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/71589811.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定