字符串

字符串的本质

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
,
世
界