为了账号安全,请及时绑定邮箱和手机立即绑定

Go 中的不可变字符串

Go 中的不可变字符串

尚方宝剑之说 2022-01-04 21:00:17
有没有人能解释一下为什么&c1.name在函数中更改后的地址是相同的changeMe()。我认为字符串在 Go 中是不可变的。package mainimport "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 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

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


字符串的不变性意味着字符串中的字符不能改变。这适用于 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)))

}


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 191 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信