Go基础数据结构学习——string
-
string在Go语言内存模型中用一个2字长的数据结构表示,一个是指向字符串存储的数据的指针,另一个为长度数据。
type stringStruct struct { str unsafe.Pointer len int }
-
由于string中不包含内存空间,只有一个内存的指针,可以方便的进行传输而不用担心内存拷贝,非常的轻量化,但是字符串字面量存储位置是只读段的,不是在堆或者栈上,所以string是不可修改的
-
string和[]byte相互转换,需要内存拷贝(申请内存空间=>拷贝数据),[]byte擅长与字符串修改和切片操作的场景,string擅长与字符串比较和不需要nil的场景
-
注意:
-
string默认值是“”,而不是nil
-
string不能和nil比较
-
len获取到的是字符串的字节数而不是字符串的字符数
对于ascii字符,一个字符占一个字节;对于非ASCII字符,比如汉字,一个字符就占3个字节。如字符串“hello北京”,它的字符长度是7,但它的字节长度是11
-
Index遍历的时候也是字节遍历的,所以中文遍历会有乱码问题
-
for-range是字符遍历的,不会出现乱码,但是下标index就有出现不连续的问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FPcw0B45-1586877765381)(/Users/hexiaohong/Library/Application Support/typora-user-images/image-20200414224923063.png)]
-
-
字符串的拼接
字符串的评价有很多种方式,比如:
-
使用“+”
hello := "hello" world := "world" helloWorld := hello + "," + world // 每次+都会产生新的临时字符串,会给 gc 带来负担,性能比较差
-
使用fmt.Sprintf
hello := "hello" world := "world" helloWorld := fmt.Sprintf("%s,%s", hello, world) // 可以用于有数字或其他的拼接,因为其他的额外判断,性能也比较差
-
strings.Join()
hello := "hello" world := "world" helloWorld := strings.Join([]string{hello, world}, ",") // join会先根据字符串数组,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高
-
使用buffer.WriteString()
hello := "hello" world := "world" var buffer bytes.Buffer buffer.WriteString(hello) buffer.WriteString(",") buffer.WriteString(world) helloWorld := buffer.String() // 性能最好
-