Rud*_*koŭ 4 string immutability go
在Go 规范中写道:
字符串是不可变的:一旦创建,就不可能改变字符串的内容.
我有以下代码:
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
Run Code Online (Sandbox Code Playgroud)
我&str
原本预计地址会改变*ptr = "world"
.正如Java所发生的那样,我们重新分配字符串引用.
什么是"不变性"?
icz*_*cza 12
string
值是不可变的.
str
不是一个string
价值.它是一个变量(string
类型).变量的值可能会改变,这就是你对任何编程语言的期望.
"hello"
是一个string
值,这是不可变的."world"
是另一个string
值,当您指定"world"
时str
,您只需为str
变量分配另一个不同的值.如果您直接str
或通过指针进行操作并不重要.您只是更改由表示的变量的值str
.
不可变意味着您无法获取string
值"world"
,例如更改其第二个字符.如果你有一个函数,例如接收一个string
参数,无论它收到什么(例如"hello"
),你可以确定它将始终保持不变.无论何时/如何打印此string
值,它始终是"hello"
.
甲string
值是在引擎盖下一个struct值,由表示的reflect.StringHeader
类型:
type StringHeader struct {
Data uintptr
Len int
}
Run Code Online (Sandbox Code Playgroud)
它基本上存储一个数据指针(到保存文本的UTF-8编码值的字节数组),以及值的字节长度string
.数据数组及其长度不会向您公开,因此您无法修改它们.这是确保string
值不可变的一个要素.另一个元素是虽然string
可以索引值(索引其字节),但是不能为索引表达式分配新值.例如,使用该值是有效的"abc"[0]
,但是为它分配新值是无效的"abc"[0] = 'x'
.同样,您不能将索引表达式的地址索引为索引string
值(否则您可以修改指向的值,从而间接修改string
值).
这是语言规范保证的.请注意,仍有某些方法可以更改string
值,例如使用包unsafe
,但这不符合规范的保证:
Package unsafe包含围绕Go程序类型安全的操作.
导入不安全的软件包可能是不可移植的,并且不受Go 1兼容性指南的保护.
您导入包装的"时刻" unsafe
,您将失去语言规范提供的任何保证和安全,从那里您不能抱怨任何事情.但是,如果不使用这些"特殊"手段,string
价值就不会发生变化.
阅读博客文章Go中的字符串,字节,符文和字符,了解如何在Gostring
中实现和工作.
查看相关问题:
go中使用从[] byte到string的不安全转换可能带来的后果是什么?