字符串本质
字符串是由若干字符组成的序列。
字符是以数字的形式存储在计算机内部的。
ASCII编码用7位二进制数表示了128(27)个字符,包括26个英文字母大小写,0-9的10个阿拉伯数字,一些标点符号、数学符号和控制字符。
Unicode编码用32位二进制数表示了128000个字符,涵盖了135种现代及古老的语言,其开头的128个字符就是ASCII字符。
每个Unicode字符,在计算机内部都会按照某种算法被转换为特定的字节序列。这种算法被称为转换格式,其中最著名且常用的是UTF-8,它的发明者同时也是Go语言的发明者之一,正是大名鼎鼎的Ken Thompson。
UTF-8编码是一种针对Unicode字符的可变长编码,用1到6个字节编码一个Unicode字符。最早的128个ASCII字符,其UTF-8编码与ASCII编码完全一样。
Go语言字符串在内存中就是由其每个字符的UTF-8编码组成的只读字节切片。
- 一个字符串在内存中的字节切片长度可通过内置函数len求得。
-
通过基零的连续下标访问字符串时,所访问的其实就是该字符串字节切片中的每个字节。(与6.1中的字符串遍历方式1对应
从字符串字节切片中提取与某个字符相对应的字节序列,经由转换格式的逆向运算,即可得到该字符的Unicode码点,这在Go语言中被定义为rune类型,即32位整型int32,专门用于表示单个字符。
- 通过包含range子句的for循环访问字符串时,所访问的其实就是组成该字符串的每个字符,rune类型的Unicode码点。(与6.1中的字符串遍历方式2对应)
处理字符串
标准库的strings包提供了一套完备的字符串处理函数,例如:
- strings.ToLower 将字符串中的大写字母转换为小写字母
- strings.Index 在字符串中查找子串,返回第一个匹配子串首字符的下标,没找到返回-1
- strings.TrimSpace 删除开头和末尾的所有空白字符
// 将字符串转为小写
// strings包的ToLower函数可将字符串中的所有大写字母转换为小写
package mainimport ("strings"
)func main() {upper := "VERY IMPORTANT MESSAGE"println(upper) // VERY IMPORTANT MESSAGElower := strings.ToLower(upper)println(lower) // very important message
}
// 查找字符串
// strings包的Index函数返回其第二个参数字符串在其第一个参数字符串中第一次出现的位置,没出现则返回-1
package mainimport ("fmt""strings"
)func main() {// 0123456s := "surface"// facefmt.Println(strings.Index(s, "face")) // 3fmt.Println(strings.Index(s, "fave")) // -1
}
// 删除首位空白字符
// strings包的TrimSpace函数删除字符串的首尾空白字符
package mainimport ("fmt""strings"
)func main() {original := ` Hello World!
`fmt.Printf("%q\n", original)// " \n \t Hello World! \t \n "trimed := strings.TrimSpace(original)fmt.Printf("%q\n", trimed)// "Hello World!"
}