字符串

字符串的本质

go内嵌string类型来表示字符串。我们来看string的本质

type StringHeader struct { Data uintptr Len int }

本质是string是个结构体,有连个字段Data是个指针指向一段字节系列(连续内存)开始的位置。Len则代表长度,内嵌函数len(s)可以获取这个长度值。

Data字段指向的是一段连续内存的起始文字,这一段内存的值是不允许改变的。

a:="aaa" // a{Data:&"aaa",Len:3} &"aaa"代表为“aaa”内存起始地址 b:=a // b{Data:&"aaa",Len:3} c:=a[2:] // c{Data:&"aaa"+2,Len:3}

字符串拼接

go字符串拼接使用+

a:="hello" + " world" b := a+"ccc"

字符串切片操作

字符串支持下标索引的方式索引到字符,s[i] i需要满足0<=i<len(s),小于0会引起编译错误,大于等于len(s)会引起运行时错误panic: index out of range

s := "hello world" fmt.Println(len(s)) //11 fmt.Println(s[2], s[7]) //108 111('l','o')

s[i]的本质是获取 Data指针指向内容第i个字节的值。由于Data指向的只是不允许改变的,所以试图改变它的值会引起编译错误

s[2] ='d' // compile error

字符串支持切片操作来产生新的字符串

s := "hello world" fmt.Println(s[0:5]) //"hello" fmt.Println(s[:5]) //"hello" 等同 s[0:5] fmt.Println(s[5:]) //" world" 等同 s[5:11] fmt.Println(s[:]) //"hello world" 等同 s[0:11]

rune

go语言中使用rune处理Unicode,go的源码文件使用的是UTF8编码。go语言使用unicode/utf8来处理utf8。

本质上runeint32的别名。

import "unicode/utf8" s := "Hello,世界" fmt.Println(len(s)) // "12" fmt.Println(utf8.RuneCountInString(s)) // "8"

需要主要字符串在用range变量的时候 会转换成[]rune

for _, v := range s { fmt.Println(string(v)) }

结果是

H e l l o , 世 界