文章目录
- 前言
- 推荐阅读
前言
最近有读者留言说,平时在写代码的过程中,是会对字符串进行修改的,但网上都说 Go 语言字符串是不可变的,这是为什么呢?
这个问题本身并不困难,但对于新手来说确实容易产生困惑,今天就来回答一下。
首先来看看它的底层结构:
type stringStruct struct {
str unsafe.Pointer
len int
}
和切片的结构很像,只不过少了一个表示容量的 cap 字段。
- str:指向一个 []byte 类型的指针
- len:字符串的长度
所以,当我们定义一个字符串:
s := "Hello World"
那么它在内存中存储是这样的:
当我们在程序中对字符串进行重新赋值时,比如这样:
s := "Hello World"
s = "Hello AlwaysBeta"
底层的存储就变成了这样:
Go 实际上是重新创建了一个 []byte{} 切片,然后让指针指向了新的地址。
更直接一点,我们直接修改字符串中的单个字符,比如:
s := "Hello World"
s[0] = 'h'
这样做的话,会直接报错:
cannot assign to s[0] (strings are immutable)
如果一定要这么做的话,需要对字符串进行一个转换,转换成 []byte 类型,修改之后再转换回 string 类型:
s := "Hello World"
sBytes := []byte(s)
sBytes[0] = 'h'
s = string(sBytes)
这样就可以了。
推荐阅读
- Go 语言教程–介绍(一)
- Go 语言教程–语言结构(二)
- Go 语言教程–语言结构(三)
- Go 语言教程–数据类型(四)
- Go 语言教程–语言变量(五)
- Go 语言教程–GO语言常量(六)
- Go 语言教程–GO语言运算符(七)
- Go 语言教程–GO条件和循环语句(八)
- Go 语言教程–GO语言函数(九)
- Go 语言教程–GO语言变量作用域(十)
- Go 语言教程–GO语言数组(十一)
- Go 语言教程–GO语言指针(十二)
- Go 语言教程–GO语言结构体(十三)
- Go 语言教程–GO语言切片(Slice)(十四)
- Go 语言教程–Go 语言范围(Range)(十五)
- Go 语言教程–Go 语言Map(集合)(十六)
- Go 语言教程–Go 语言递归函数(十七)
- Go 语言教程–Go 语言类型转换(十八)
- Go 语言教程–Go 语言接口(十九)
- Go 语言教程–Go 错误处理(二十)
- Go 语言教程–Go 并发(二十一)