英文:
Immutable strings in Go
问题
有人能解释一下为什么在函数changeMe()
中修改后,&c1.name
的地址仍然相同吗?我以为在Go语言中字符串是不可变的。
package main
import "fmt"
type customer struct {
name string
age int
}
func main() {
c1 := customer{"Todd", 44}
fmt.Println(&c1.name) // 0x8201e4120
changeMe(&c1)
fmt.Println(c1) // {Rocky 44}
fmt.Println(&c1.name) // 0x8201e4120
}
func changeMe(z *customer) {
fmt.Println(z) // &{Todd 44}
fmt.Println(&z.name) // 0x8201e4120
z.name = "Rocky"
fmt.Println(z) // &{Rocky 44}
fmt.Println(&z.name) // 0x8201e4120
}
英文:
is anyone able to explain me why the address of &c1.name
is the same after being changed in function changeMe()
. I thought strings are immutable in Go.
package main
import "fmt"
type customer struct {
name string
age int
}
func main() {
c1 := customer{"Todd", 44}
fmt.Println(&c1.name) // 0x8201e4120
changeMe(&c1)
fmt.Println(c1) // {Rocky 44}
fmt.Println(&c1.name) // 0x8201e4120
}
func changeMe(z *customer) {
fmt.Println(z) // &{Todd 44}
fmt.Println(&z.name) // 0x8201e4120
z.name = "Rocky"
fmt.Println(z) // &{Rocky 44}
fmt.Println(&z.name) // 0x8201e4120
}
答案1
得分: 17
字符串的不可变性与变量的不可变性不同。
字符串的不可变性意味着字符串中的字符不能被改变。这在Go语言中是成立的。Go语言在切片字符串时使用了这一特性,如下面的示例所示。
Go语言中的变量始终是可变的。当一个字符串变量被改变时,变量的内部字段(指针和长度)会被改变,但变量的地址不会改变。
下面的示例展示了Go语言字符串变量的内部结构。第一个整数是字符数组的地址,第二个整数是长度。
请参阅关于Go语言字符串内部结构的文章http://research.swtch.com/godata。
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
var x string = "abc"
fmt.Println(x, &x, (*reflect.StringHeader)(unsafe.Pointer(&x)))
x = "cde"
fmt.Println(x, &x, (*reflect.StringHeader)(unsafe.Pointer(&x)))
x = x[1:]
fmt.Println(x, &x, (*reflect.StringHeader)(unsafe.Pointer(&x)))
}
英文:
The immutability of strings is not the same as immutability of variables.
Immutability of strings means that the characters in the string cannot be changed. This holds true for Go. Go makes use of it when slicing strings as shown in the example below.
Variables in Go are always mutable. When a string variable is changed, the internal fields of the variable (pointer and length) are changed. The address of variable never changes.
The example below presents the internals of Go string variable. The first integer is an address to the array of characters and the second is the length.
See the article on internals of string in Go http://research.swtch.com/godata.
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
var x string = "abc"
fmt.Println(x, &x, (*reflect.StringHeader)(unsafe.Pointer(&x)))
x = "cde"
fmt.Println(x, &x, (*reflect.StringHeader)(unsafe.Pointer(&x)))
x = x[1:]
fmt.Println(x, &x, (*reflect.StringHeader)(unsafe.Pointer(&x)))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论