一个字符串是一个不可改变的字节序列,字符串的元素不可修改(元素不可更改,字符串变量可以重新赋值),是一个只读的字节数组。所以字符串的长度是固定的,但是跟数组不一样,字符串长度不是字符串类型的一部分。
go字符串底层结构如下:
type StringHeader struct {
Data uintptr //指向字节数组的指针
Len int //字节数组长度
}
字符串变量相当于一个结构体,所以字符串的赋值不会涉及到字节数组的复制。
字符串用法如下:
package main
import "fmt"
func main() {
var str1 = "he好"
println(len(str1)) //5
println(len([]rune(str1))) //3
println(str1[0:1]) //h
for i, v := range str1 {
fmt.Printf("i=%v v=%c v= %v\n", i,v,v)
//i=0 v=h v= 104
//i=1 v=e v= 101
//i=2 v=好 v= 22909
}
for i,c := range []byte(str1) {
fmt.Println(i,c)
//0 104
//1 101
//2 229
//3 165
//4 189
}
var str3 = []rune(str1)
str3[2] = '改'
println(string(str3))//he改
fmt.Printf("%#v\n", []rune("世界")) // []int32{19990, 30028}
fmt.Printf("%#v\n", string([]rune{'世','界'}))//"世界"
}
解析:
- len()函数作用于字符串,取的是底层的bype数组的长度。如果想要取字符个数,可以先转为rune数组,再用len()函数。
- 字符串支持切片操作。
- range作用于字符串,得到的是UTF8解码后的Unicode码点值,也就是字符串字面量。如果需要遍历底层字节码,可以转成byte数组,再进行遍历。
- rune其实就是int32类型,rune用于表示每个unicode码点。如果想修改字符串,可以转成rune数组(如果有中文等字符),再进行修改,然后再转成字符串。