gpt4 book ai didi

string - Go 中的不可变字符串

转载 作者:IT王子 更新时间:2023-10-29 01:49:17 26 4
gpt4 key购买 nike

谁能给我解释一下,为什么&c1.name 的地址在函数changeMe() 中改变后是一样的。我认为字符串在 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
}

最佳答案

字符串的不变性与变量的不变性不同。

字符串的不变性意味着字符串中的字符不能被改变。这适用于围棋。 Go 在 slice 字符串时使用它,如下例所示。

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)))
}

Playground

关于string - Go 中的不可变字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36720693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com