2214 - 字符串
33========================
44
5- 上一节:[ 第十篇 if else 语句 ] ( /docs/golang_tutorial_10 .md )
6- 下一节:[ 第十二篇 包 ] ( /docs/golang_tutorial_12 .md )
5+ 上一节:[ 第十三篇 Map ] ( /docs/golang_tutorial_13 .md )
6+ 下一节:[ 第十五篇 指针 ] ( /docs/golang_tutorial_15 .md )
77
88这是本Golang系列教程的第14篇。
99
@@ -32,7 +32,9 @@ func main() {
3232 printBytes (name)
3333}
3434```
35- 在上面的程序中,` len(s) ` 返回字符串中的字节数,我们用一个 ` for ` 循环以 16 进制打印这些字节。` %x ` 格式化指示符用来以 16 进制打印参数。上面的程序打印:` 48 65 6c 6c 6f 20 57 6f 72 6c 64 ` 。它们是 ` "Hello World" ` 以` UTF-8 ` 方式编码的` Unicode ` 值。对 ` Unicode ` 字符集和 ` UTF-8 ` 编码有一个基本的了解会更好的理解 ` string ` 类型。我(原文作者)建议大家阅读:https://naveenr.net/unicode-character-set-and-utf-8-utf-16-utf-32-encoding/ 来学习什么是 ` Unicode ` 和 ` UTF-8 ` 。
35+ 在上面的程序中,` len(s) ` 返回字符串中的字节数,我们用一个 ` for ` 循环以 16 进制打印这些字节。` %x ` 格式化指示符用来以 16 进制打印参数。上面的程序打印:` 48 65 6c 6c 6f 20 57 6f 72 6c 64 ` 。它们是 ` "Hello World" ` 以 ` UTF-8 ` 方式编码的 ` Unicode ` 值。对 ` Unicode ` 字符集和 ` UTF-8 ` 编码有一个基本的了解会更好的理解 ` string ` 类型。我(原文作者)建议大家阅读:https://naveenr.net/unicode-character-set-and-utf-8-utf-16-utf-32-encoding/ 来学习什么是 ` Unicode ` 和 ` UTF-8 ` 。
36+
37+ ## 访问字符串中的字符
3638
3739让我们修改上面的程序以打印字符串中的字符:
3840
@@ -63,6 +65,7 @@ func main() {
6365 printChars (name)
6466}
6567```
68+
6669在第 16 行的 ` printChars ` 函数中,` %c ` 格式化指示符用来打印字符串中的字符。上面的程序输出为:
6770
6871``` golang
@@ -103,14 +106,18 @@ func main() {
103106 printChars (name)
104107}
105108```
109+
106110上面程序的输出为:
111+
107112``` golang
10811348 65 6c 6c 6f 20 57 6f 72 6c 64
109114Hello World
11011553 65 c3 b1 6f 72
111116Señor
112117```
113118
119+ 我们尝试将 ` "Señor" ` 中的每个字符打印出来,但是却得到了 ` "Señor" ` 。为什么这个程序在 ` "Hello World" ` 上运行正常,但是不适用于 ` "Señor" ` 呢?因为 ` ñ ` 的 ` Unicode ` 码点是 ` U+00F1 ` ,因而它的 ` UTF-8 ` 编码占了两个字节:` c3 ` 和 ` b1 ` 。上面的程序假定每个码点只有一个字节长度,因此会发生错误。** 在 ` UTF-8 ` 编码中,一个码点可能会占一个以上的字节。** 在这种情况下,我们需要 ` rune ` 来帮助解决问题。
120+
114121## rune
115122
116123` rune ` 是 Go 中的内置类型,它是 ` int32 ` 的别名。在 Go 中,` rune ` 表示一个 ` Unicode ` 码点。无论一个码点会被编码为多少个字节,它都可以表示为一个 ` rune ` 。让我们修改上面的程序,使用 ` rune ` 来打印字符串中的字符。
@@ -148,19 +155,20 @@ func main() {
148155}
149156```
150157
151- 在上面的程序中,第 14 行,字符串被转换为 ` tune ` 切片。然后我们遍历该切片并打印其中的字符。程序的输出如下:
158+ 在上面的程序中,第 14 行,字符串被转换为 ` rune ` 切片。然后我们遍历该切片并打印其中的字符。程序的输出如下:
152159
153160``` golang
15416148 65 6c 6c 6f 20 57 6f 72 6c 64
155162Hello World
15616353 65 c3 b1 6f 72
157164Señor
158165```
159- 上面的输出是正确的。这正是我们想要的结果。
160166
161- ## 使用 range for 遍历字符串
167+ 上面的输出是正确的,这正是我们想要的结果。
168+
169+ ## 使用 for range 遍历字符串
162170
163- 上面的程序是遍历字符串中字符的一个正确方式。但是 Go 提供了一种更简单的方式来做到这一点:使用 ` range ` ` for ` 。
171+ 上面的程序是遍历字符串中字符的一个正确方式。但是 Go 提供了一种更简单的方式来做到这一点:使用 ` for range` 循环 。
164172
165173``` golang
166174package main
@@ -181,7 +189,7 @@ func main() {
181189}
182190```
183191
184- 在上面的程序中,第 8 行通过使用 ` range for` 遍历字符串。 ` range ` 返回一个 ` rune ` (在 ` byte ` 数组中)的位置,以及 ` rune ` 本身。上面的程序输出为:
192+ 在上面的程序中,第 8 行通过使用 ` for range ` 循环遍历字符串。该循环返回一个 ` rune ` (在 ` byte ` 数组中)的位置,以及 ` rune ` 本身。上面的程序输出为:
185193
186194``` golang
187195S starts at byte 0
@@ -191,7 +199,7 @@ o starts at byte 4
191199r starts at byte 5
192200```
193201
194- 从上面的输出可以看到,ñ 占两个字节:)
202+ 从上面的输出可以看到,ñ 占两个字节 :)
195203
196204## 通过 ` byte ` 切片创建字符串
197205
@@ -208,6 +216,7 @@ func main() {
208216 fmt.Println (str)
209217}
210218```
219+
211220在上面的程序中,` byteSlice ` 是 ` "Café" ` 经过 ` UTF-8 ` 编码后得到的切片(用 16 进制表示) 。上面的程序输出为:` Café ` 。
212221
213222如果我们换成对应的十进制数程序会正常工作吗?答案是:` Yes ` 。让我们测试一下:
@@ -225,9 +234,11 @@ func main() {
225234 fmt.Println (str)
226235}
227236```
237+
228238上面的程序同样输出:` Café ` 。
229239
230- ## 通过 rune 切片创建字符串
240+ ## 通过 ` rune ` 切片创建字符串
241+
231242``` golang
232243package main
233244
@@ -241,12 +252,14 @@ func main() {
241252 fmt.Println (str)
242253}
243254```
255+
244256在上面的程序中,` runeSlice ` 包含了字符串 ` "Señor" ` 的 ` Unicode ` 码点(以 16 进制表示)。程序的输出为:` Señor ` 。
245257
246- ## 字符串的长度
258+ ## 字符串的长度
259+
247260utf8 包 提供了 ` func RuneCountInString(s string) (n int) ` 来获取字符串的长度,该方法接受一个字符串作为参数,并返回该字符串中 ` rune ` 的数量。
248261
249- (译者注: ` RuneCountInString ` 返回字符串中 ` Unicode ` 字符的个数,而 ` len ` 返回字符串中 ` byte ` 的个数,注意两者的区别。 )
262+ (译者注:` RuneCountInString ` 返回字符串中 ` Unicode ` 字符的个数,而 ` len ` 返回字符串中 ` byte ` 的个数。因此用 ` len ` 来获取字符串长度可能会导致错误。 )
250263
251264``` golang
252265package main
@@ -296,7 +309,7 @@ func main() {
296309}
297310```
298311
299- 上面的程序中,第 8 行我们试图改变字符串的第一个字符为 ` a ` 。因为字符串是不可变的 ,因此这是非法的,将会报错:` main.go:8: cannot assign to s[0] ` 。
312+ 上面的程序中,第 8 行我们试图改变字符串的第一个字符为 ` a ` 。任何在单引号内的 ` Unicode ` 字符都是 ` rune ` 。由于字符串是不可变的 ,因此这是非法的,将会报错:` main.go:8: cannot assign to s[0] ` 。
300313
301314** 为了改变一个字符串中的字符,我们需要先把字符串转换为 ` rune ` 切片,然后修改切片中的内容,最后将这个切片转换回字符串** 。
302315
@@ -317,6 +330,6 @@ func main() {
317330}
318331```
319332
320- 在上面的程序中,第 7 行 ` mutate ` 函数接受一个 ` rune ` 切片作为参数。然后将该切片的第一个元素改为 ` a ` ,最后再转换回字符串并返回。该函数在程序中的第 13 行被调用。` h ` 被转换为一个 ` rune ` 切片传递给 ` mutate ` 。程序的输出为:` aello ` 。
333+ 在上面的程序中,第 7 行 ` mutate ` 函数接收一个 ` rune ` 切片作为参数。然后将该切片的第一个元素改为 ` a ` ,最后再转换回字符串并返回。该函数在程序中的第 13 行被调用。` h ` 被转换为一个 ` rune ` 切片传递给 ` mutate ` 。程序的输出为:` aello ` 。
321334
322335字符串的介绍到此为止。感谢阅读。
0 commit comments