Characters and Strings
在Go语言中,字符可以由两种方式表示。单个字符可以由单个rune(or int32)表示。 从现在开始我们使用专业术语"Character", "Code point", "Unicode character" 和 "Unicode code point" 表示单个字符。 Go strings是由0个或者多个characters组成的字符序列。在一个字符串中每一个字符又是由一个或者多个UTF-8编码过的字节(bytes)组成。
我们可以将单个字符,对过string(char)转换为只有一个字符的字符串。 如下所示
æs := ""
for _, char := range []rune{'æ', 0xE6, 0346, 230, '\xE6', '\u00E6'} {
fmt.Printf("[0x%X '%c'] ", char, char)
æs += string(char)
}
[0xE6 'æ'][0xE6 'æ'][0xE6 'æ'][0xE6 'æ'][0xE6 'æ'][0xE6 'æ']
一个字符串可以通过chars := []rune(s)的语法转换为rune slice. 这对于我们需要挨个解析每个字符时非常有用。 相反的操作是 s := string(chars) 将一个[]rune或才[]int32 slice转换为字符串。 这种转换的时间是0(n).
字符串连接可以使用最方便, 最简单的 string += 的方式,但这种方式的效率最低,一种更好的方式是像Python那样,一次性把所有的字符串存入一个字符串数组,然后通过strings.Join()函数,连接各个字符串.Go还提供了一种更好的方法, 类似于Java's StringBuilder.
æs := []string{"hello", "中国", "开发语言"}
fmt.Println(strings.Join(æs, "test"))
var buffer bytes.Buffer //创建一个空的bytes.Buffer
for {
if piece, ok := getNextValidString(); ok {
buffer.WriteString(piece) //通过WriteString将字符串写入buffer
} else {
break
}
}
fmt.Print(buffer.String(), "\n")//String()取出字符串
bytes.Buffer要比 +=运算符更有效率,但也占用更多的内存和CPU.
for ... range loop 可以用于character by character遍历字符串。每一次遍历生成一个index和代码点(code point).
phrase := "vått og tørt"
fmt.Printf("strings: %s\n", phrase)
fmt.Println("index rune char bytes")
for index, char := range phrase {
// for ... range 会对UTF-8字节数组解码为 Unicode字符码(runes).
fmt.Printf("%-2d %U '%c' % X\n", index,
char, char, []byte(string(char)))
//获得bytes, 我们先需要将单个char, 转化为string(获得UTF-8的编码字节),在将这单个字符的字符串,转变为 bytes
strings: vått og tørt
index rune char bytes
0 U+0076 'v' 76
1 U+00E5 'å' C3 A5
3 U+0074 't' 74
4 U+0074 't' 74
5 U+0020 ' ' 20
6 U+006F 'o' 6F
7 U+0067 'g' 67
8 U+0020 ' ' 20
9 U+0074 't' 74
10 U+00F8 'ø' C3 B8
12 U+0072 'r' 72
13 U+0074 't' 74
为了获得每个字符的字节,我们先将code point(rune)转换为string. 然后将这个只有单个字符的字符串转换为[]byte slice, 这样我们才能真正的访问实现的字节bytes. []byte(string)的转换非常快(0(1)).