不变的字符串和指针地址 [英] Immutable string and pointer address
问题描述
在Go 规范中写道:
字符串是不可变的:一旦创建,就无法更改 字符串的内容.
Strings are immutable: once created, it is impossible to change the contents of a string.
我有以下代码:
str := "hello"
fmt.Printf("%p\n",&str) // 0x1040c128
fmt.Printf("%v\n",str) // hello
ptr := &str
*ptr = "world"
fmt.Printf("%p\n",&str) // 0x1040c128
fmt.Printf("%v\n",str) // world
我希望在*ptr = "world"
之后更改&str
地址.就像Java那样,我们在其中重新分配String引用.
I would have expected &str
address was changed after *ptr = "world"
. As it would happen with Java, where we reassign String references.
什么是不变性"?
推荐答案
string
值是不可变的.
str
不是string
值.这是变量(属于string
类型).并且变量的值可能会更改,这是您对任何编程语言所期望的.
str
is not a string
value. It's a variable (of string
type). And values of variables may be changed, that's what you'd expect from any programming language.
"hello"
是一个string
值,这是不可变的. "world"
是另一个string
值,将"world"
分配给str
时,只需将另一个不同的值分配给str
变量.可以直接对str
进行操作,也可以通过指针进行操作.您只是在更改由str
表示的变量的值.
"hello"
is a string
value, and this is what is immutable. "world"
is another string
value, and when you assign "world"
to str
, you just assign another, different value to the str
variable. It doesn't matter if you're doing it directly to str
, or via a pointer. You're just changing the value of the variable denoted by str
.
不可变的表示您不能采用string
值"world"
,例如,更改其第二个字符.例如,如果您有一个函数接收一个string
自变量,无论它接收到什么(例如"hello"
),都可以确保它始终保持不变.无论何时/如何打印此string
值,它始终为"hello"
.
Immutable means you cannot take the string
value "world"
, and change its second character for example. If you have a function for example which receives a string
argument, whatever it receives (e.g. "hello"
), you can be sure it will always remain the same. No matter when / how you print this string
value, it will always be "hello"
.
string
值是一个底层结构值,由 reflect.StringHeader
类型:
A string
value is a struct value under the hood, represented by the reflect.StringHeader
type:
type StringHeader struct {
Data uintptr
Len int
}
它基本上存储一个数据指针(指向保存文本的UTF-8编码值的字节数组)和string
值的字节长度.数据数组及其长度不向您公开,因此您无法对其进行修改.这是确保string
值不可变的元素之一.另一个元素是,尽管可以为string
值建立索引(索引其字节),但是您不能将新值分配给索引表达式.例如.使用值"abc"[0]
是有效的,但是像"abc"[0] = 'x'
这样为其分配新值是无效的.同样,您不能获取索引string
值的索引表达式的地址(否则可以修改指向的值,从而间接地修改string
值).
It basically stores a data pointer (to the byte array holding the UTF-8 encoded value of the text), and the byte-length of the string
value. The data array and its length are not exposed to you, so you can't modify them. This is one element of making sure that string
values are immutable. Another element is that although string
values can be indexed (which indexes its bytes), you can not assign new values to the index expressions. E.g. it is valid to use the value "abc"[0]
, but it is invalid to assign a new value to it like "abc"[0] = 'x'
. Similarly, you cannot take the address of an index expression indexing a string
value (else you could modify the pointed value and thus indirectly the string
value).
这是语言规范的保证.请注意,有些方法仍然可以更改string
值,例如使用软件包 unsafe
,但这超出了规范的保证范围:
This is what the language spec guarantees. Note that there are certain ways to still change string
values, e.g. using package unsafe
, but this falls outside the guarantees of the spec:
不安全打包包含围绕Go程序的类型安全性进行的操作.
Package unsafe contains operations that step around the type safety of Go programs.
导入不安全的软件包可能是不可携带的,并且不受Go 1兼容性准则的保护.
Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.
时刻"导入软件包unsafe
,您将失去语言规范所提供的任何保证和安全,并且从那时起您就不会有任何抱怨.但是,在没有使用这些特殊"功能的情况下,没有意味着string
值不会被更改.
The "moment" you import package unsafe
, you'll lose any guarantees and safety provided by the language spec, and from there on you can't complain for anything. But without using these "special" means, it cannot happen that a string
value gets altered.
阅读博客文章 Go中的字符串,字节,符文和字符,了解如何实现string
并可以在Go中使用.
Read the blog post Strings, bytes, runes and characters in Go for how string
is implemented and works in Go.
查看相关问题:
在go中使用从[]字节到字符串的不安全转换有什么可能的后果?
这篇关于不变的字符串和指针地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!