mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 00:43:26 +08:00
@@ -1,8 +1,8 @@
|
||||
# 5.4 for 结构
|
||||
|
||||
如果想要重复执行某些语句,Go 语言中您只有 for 结构可以使用。不要小看它,这个 for 结构比其它语言中的更为灵活。
|
||||
如果想要重复执行某些语句,Go 语言中您只有 `for` 结构可以使用。不要小看它,这个 `for` 结构比其它语言中的更为灵活。
|
||||
|
||||
**注意事项** 其它许多语言中也没有发现和 do while 完全对等的 for 结构,可能是因为这种需求并不是那么强烈。
|
||||
**注意事项** 其它许多语言中也没有发现和 do-while 完全对等的 `for` 结构,可能是因为这种需求并不是那么强烈。
|
||||
|
||||
## 5.4.1 基于计数器的迭代
|
||||
|
||||
@@ -32,7 +32,7 @@ func main() {
|
||||
This is the 3 iteration
|
||||
This is the 4 iteration
|
||||
|
||||
由花括号括起来的代码块会被重复执行已知次数,该次数是根据计数器(此例为 i)决定的。循环开始前,会执行且仅会执行一次初始化语句 `i := 0;`;这比在循环之前声明更为简短。紧接着的是条件语句 `i < 5;`,在每次循环开始前都会进行判断,一旦判断结果为 false,则退出循环体。最后一部分为修饰语句 `i++`,一般用于增加或减少计数器。
|
||||
由花括号括起来的代码块会被重复执行已知次数,该次数是根据计数器(此例为 `i`)决定的。循环开始前,会执行且仅会执行一次初始化语句 `i := 0;`;这比在循环之前声明更为简短。紧接着的是条件语句 `i < 5;`,在每次循环开始前都会进行判断,一旦判断结果为 `false`,则退出循环体。最后一部分为修饰语句 `i++`,一般用于增加或减少计数器。
|
||||
|
||||
这三部分组成的循环的头部,它们之间使用分号 `;` 相隔,但并不需要括号 `()` 将它们括起来。例如:`for (i = 0; i < 10; i++) { }`,这是无效的代码!
|
||||
|
||||
@@ -46,7 +46,7 @@ func main() {
|
||||
for i, j := 0, N; i < j; i, j = i+1, j-1 {}
|
||||
```
|
||||
|
||||
这得益于 Go 语言具有的平行赋值的特性(可以查看第 7 章 string_reverse.go 中反转数组的示例)。
|
||||
这得益于 Go 语言具有的平行赋值的特性(可以查看[第 7 章](07.0.md) [string_reverse.go](.\examples\chapter_7\string_reverse.go) 中反转数组的示例)。
|
||||
|
||||
您可以将两个 for 循环嵌套起来:
|
||||
|
||||
@@ -122,16 +122,16 @@ func main() {
|
||||
Character on position 7 is: ª
|
||||
Character on position 8 is:
|
||||
|
||||
如果我们打印 str 和 str2 的长度,会分别得到 27 和 9。
|
||||
如果我们打印 `str` 和 `str2` 的长度,会分别得到 `27` 和 `9`。
|
||||
|
||||
由此我们可以发现,ASCII 编码的字符占用 1 个字节,既每个索引都指向不同的字符,而非 ASCII 编码的字符(占有 2 到 4 个字节)不能单纯地使用索引来判断是否为同一个字符。我们会在第 5.4.4 节解决这个问题。
|
||||
由此我们可以发现,ASCII 编码的字符占用 1 个字节,既每个索引都指向不同的字符,而非 ASCII 编码的字符(占有 2 到 4 个字节)不能单纯地使用索引来判断是否为同一个字符。我们会在[第 5.4.4 节](05.4.md) 解决这个问题。
|
||||
|
||||
### 练习题
|
||||
|
||||
**练习 5.4** [for_loop.go](exercises/chapter_5/for_loop.go)
|
||||
|
||||
1. 使用 for 结构创建一个简单的循环。要求循环 15 次然后使用 fmt 包来打印计数器的值。
|
||||
2. 使用 goto 语句重写循环,要求不能使用 for 关键字。
|
||||
1. 使用 `for` 结构创建一个简单的循环。要求循环 15 次然后使用 `fmt` 包来打印计数器的值。
|
||||
2. 使用 `goto` 语句重写循环,要求不能使用 `for` 关键字。
|
||||
|
||||
**练习 5.5** [for_character.go](exercises/chapter_5/for_character.go)
|
||||
|
||||
@@ -211,7 +211,7 @@ for t, err = p.Token(); err == nil; t, err = p.Token() {
|
||||
|
||||
## 5.4.4 for-range 结构
|
||||
|
||||
这是 Go 特有的一种的迭代结构,您会发现它在许多情况下都非常有用。它可以迭代任何一个集合(包括数组和 map,详见第 7 和 8 章)。语法上很类似其它语言中 foreach 语句,但您依旧可以获得每次迭代所对应的索引。一般形式为:`for ix, val := range coll { }`。
|
||||
这是 Go 特有的一种的迭代结构,您会发现它在许多情况下都非常有用。它可以迭代任何一个集合(包括数组和 `map`,详见第 [7](07.0.md) 和 [8](08.0.md) 章)。语法上很类似其它语言中的 foreach 语句,但您依旧可以获得每次迭代所对应的索引。一般形式为:`for ix, val := range coll { }`。
|
||||
|
||||
要注意的是,`val` 始终为集合中对应索引的值拷贝,因此它一般只具有只读性质,对它所做的任何修改都不会影响到集合中原有的值(**译者注:如果 `val` 为指针,则会产生指针的拷贝,依旧可以修改集合中的原值**)。一个字符串是 Unicode 编码的字符(或称之为 `rune`)集合,因此您也可以用它迭代字符串:
|
||||
|
||||
@@ -221,7 +221,7 @@ for pos, char := range str {
|
||||
}
|
||||
```
|
||||
|
||||
每个 rune 字符和索引在 for-range 循环中是一一对应的。它能够自动根据 UTF-8 规则识别 Unicode 编码的字符。
|
||||
每个 `rune` 字符和索引在 for-range 循环中是一一对应的。它能够自动根据 UTF-8 规则识别 Unicode 编码的字符。
|
||||
|
||||
示例 5.9 [range_string.go](examples/chapter_5/range_string.go):
|
||||
|
||||
@@ -311,9 +311,9 @@ index int(rune) rune char bytes
|
||||
15 35486 U+8A9E '語' E8 AA 9E
|
||||
```
|
||||
|
||||
请将输出结果和 Listing 5.7(for_string.go)进行对比。
|
||||
请将输出结果和 Listing 5.7([for_string.go](examples/chapter_5/for_string.go))进行对比。
|
||||
|
||||
我们可以看到,常用英文字符使用 1 个字节表示,而汉字(**译者注:严格来说,“Chinese: 日本語”的Chinese应该是Japanese**)使用 3 个字符表示。
|
||||
我们可以看到,常用英文字符使用 1 个字节表示,而汉字(**译者注:严格来说,“Chinese: 日本語”的 Chinese 应该是 Japanese**)使用 3 个字符表示。
|
||||
|
||||
**练习 5.9** 以下程序的输出结果是什么?
|
||||
|
||||
|
Reference in New Issue
Block a user