在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ GO/ 5.4 for 結(jié)構(gòu)
4.7 strings 和 strconv 包
13.6 啟動(dòng)外部命令和程序
?# 11.4 類型判斷:type-switch
12.1 讀取用戶的輸入
10.6 方法
12.2 文件讀寫
13 錯(cuò)誤處理與測(cè)試
9.3 鎖和 sync 包
12.3 文件拷貝
?# 11.7 第一個(gè)例子:使用 Sorter 接口排序
?# 11.5 測(cè)試一個(gè)值是否實(shí)現(xiàn)了某個(gè)接口
6.4 defer 和追蹤
12.10 XML 數(shù)據(jù)格式
13.10 性能調(diào)試:分析并優(yōu)化 Go 程序
?# 11.1 接口是什么
2.2 Go 環(huán)境變量
2.6 安裝目錄清單
2.5 在 Windows 上安裝 Go
11.11 Printf 和反射
1.2 語(yǔ)言的主要特性與發(fā)展的環(huán)境和影響因素
9.0 包(package)
7.4 切片重組(reslice)
13.2 運(yùn)行時(shí)異常和 panic
10.2 使用工廠方法創(chuàng)建結(jié)構(gòu)體實(shí)例
12.8 使用接口的實(shí)際例子:fmt.Fprintf
2.4 在 Mac OS X 上安裝 Go
3.8 Go 性能說(shuō)明
7.2 切片
8.0 Map
3.1 Go 開(kāi)發(fā)環(huán)境的基本要求
5.6 標(biāo)簽與 goto
6.10 使用閉包調(diào)試
9.5 自定義包和可見(jiàn)性
4.3 常量
?# 11.2 接口嵌套接口
6.5 內(nèi)置函數(shù)
前言
10.8 垃圾回收和 SetFinalizer
2.8 Go 解釋器
13.7 Go 中的單元測(cè)試和基準(zhǔn)測(cè)試
6.8 閉包
4.9 指針
13.1 錯(cuò)誤處理
10.1 結(jié)構(gòu)體定義
5.1 if-else 結(jié)構(gòu)
6.6 遞歸函數(shù)
9.9 通過(guò) Git 打包和安裝
2.7 Go 運(yùn)行時(shí)(runtime)
10.7 類型的 String() 方法和格式化描述符
3.7 其它工具
9.6 為自定義包使用 godoc
11.12 接口與動(dòng)態(tài)類型
13.3 從 panic 中恢復(fù)(Recover)
10.3 使用自定義包中的結(jié)構(gòu)體
11.14 結(jié)構(gòu)體、集合和高階函數(shù)
3.6 生成代碼文檔
9.2 regexp 包
4.1 文件名、關(guān)鍵字與標(biāo)識(shí)符
?# 11.6 使用方法集與接口
7.0 數(shù)組與切片
7.1 聲明和初始化
12.11 用 Gob 傳輸數(shù)據(jù)
5.5 Break 與 continue
1.1 起源與發(fā)展
?# 11 接口(Interfaces)與反射(reflection)
6.9 應(yīng)用閉包:將函數(shù)作為返回值
4.2 Go 程序的基本結(jié)構(gòu)和要素
8.6 將 map 的鍵值對(duì)調(diào)
6.11 計(jì)算函數(shù)執(zhí)行時(shí)間
5.0 控制結(jié)構(gòu)
10.5 匿名字段和內(nèi)嵌結(jié)構(gòu)體
4.6 字符串
3.0 編輯器、集成開(kāi)發(fā)環(huán)境與其它工具
13.8 測(cè)試的具體例子
7.6 字符串、數(shù)組和切片的應(yīng)用
8.4 map 類型的切片
3.9 與其它語(yǔ)言進(jìn)行交互
7.3 For-range 結(jié)構(gòu)
9.7 使用 go install 安裝自定義包
6.0 函數(shù)
9.8 自定義包的目錄結(jié)構(gòu)、go install 和 go test
6.3 傳遞變長(zhǎng)參數(shù)
13.9 用(測(cè)試數(shù)據(jù))表驅(qū)動(dòng)測(cè)試
11.9 空接口
8.1 聲明、初始化和 make
6.2 函數(shù)參數(shù)與返回值
9.11 在 Go 程序中使用外部庫(kù)
3.3 調(diào)試器
4.5 基本類型和運(yùn)算符
?# 11.8 第二個(gè)例子:讀和寫
12.5 用 buffer 讀取文件
總結(jié):Go 中的面向?qū)ο?/span>
11.10 反射包
12.7 用 defer 關(guān)閉文件
9.4 精密計(jì)算和 big 包
4.4 變量
6.1 介紹
13.4 自定義包中的錯(cuò)誤處理和 panicking
12.4 從命令行讀取參數(shù)
9.10 Go 的外部包和項(xiàng)目
8.3 for-range 的配套用法
3.5 格式化代碼
10.4 帶標(biāo)簽的結(jié)構(gòu)體
7.5 切片的復(fù)制與追加
?# 11.3 類型斷言:如何檢測(cè)和轉(zhuǎn)換接口變量的類型
5.4 for 結(jié)構(gòu)
4.8 時(shí)間和日期
2.3 在 Linux 上安裝 Go
12 讀寫數(shù)據(jù)
6.12 通過(guò)內(nèi)存緩存來(lái)提升性能
9.1 標(biāo)準(zhǔn)庫(kù)概述
12.6 用切片讀寫文件
10 結(jié)構(gòu)(struct)與方法(method)
8.5 map 的排序
12.9 JSON 數(shù)據(jù)格式
13.5 一種用閉包處理錯(cuò)誤的模式
3.2 編輯器和集成開(kāi)發(fā)環(huán)境
12.12 Go 中的密碼學(xué)
5.2 測(cè)試多返回值函數(shù)的錯(cuò)誤
6.7 將函數(shù)作為參數(shù)
8.2 測(cè)試鍵值對(duì)是否存在及刪除元素
3.4 構(gòu)建并運(yùn)行 Go 程序
2.1 平臺(tái)與架構(gòu)
5.3 switch 結(jié)構(gòu)

5.4 for 結(jié)構(gòu)

如果想要重復(fù)執(zhí)行某些語(yǔ)句,Go 語(yǔ)言中您只有 for 結(jié)構(gòu)可以使用。不要小看它,這個(gè) for 結(jié)構(gòu)比其它語(yǔ)言中的更為靈活。

注意事項(xiàng) 其它許多語(yǔ)言中也沒(méi)有發(fā)現(xiàn)和 do while 完全對(duì)等的 for 結(jié)構(gòu),可能是因?yàn)檫@種需求并不是那么強(qiáng)烈。

5.4.1 基于計(jì)數(shù)器的迭代

文件 for1.go 中演示了最簡(jiǎn)單的基于計(jì)數(shù)器的迭代,基本形式為:

for 初始化語(yǔ)句; 條件語(yǔ)句; 修飾語(yǔ)句 {}

示例 5.6 for1.go

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Printf("This is the %d iteration\n", i)
    }
}

輸出:

This is the 0 iteration
This is the 1 iteration
This is the 2 iteration
This is the 3 iteration
This is the 4 iteration

由花括號(hào)括起來(lái)的代碼塊會(huì)被重復(fù)執(zhí)行已知次數(shù),該次數(shù)是根據(jù)計(jì)數(shù)器(此例為 i)決定的。循環(huán)開(kāi)始前,會(huì)執(zhí)行且僅會(huì)執(zhí)行一次初始化語(yǔ)句 i := 0;;這比在循環(huán)之前聲明更為簡(jiǎn)短。緊接著的是條件語(yǔ)句 i < 5;,在每次循環(huán)開(kāi)始前都會(huì)進(jìn)行判斷,一旦判斷結(jié)果為 false,則退出循環(huán)體。最后一部分為修飾語(yǔ)句 i++,一般用于增加或減少計(jì)數(shù)器。

這三部分組成的循環(huán)的頭部,它們之間使用分號(hào) ; 相隔,但并不需要括號(hào) () 將它們括起來(lái)。例如:for (i = 0; i < 10; i++) { },這是無(wú)效的代碼!

同樣的,左花括號(hào) { 必須和 for 語(yǔ)句在同一行,計(jì)數(shù)器的生命周期在遇到右花括號(hào) } 時(shí)便終止。一般習(xí)慣使用 i、j、z 或 ix 等較短的名稱命名計(jì)數(shù)器。

特別注意,永遠(yuǎn)不要在循環(huán)體內(nèi)修改計(jì)數(shù)器,這在任何語(yǔ)言中都是非常差的實(shí)踐!

您還可以在循環(huán)中同時(shí)使用多個(gè)計(jì)數(shù)器:

for i, j := 0, N; i < j; i, j = i+1, j-1 {}

這得益于 Go 語(yǔ)言具有的平行賦值的特性(可以查看第 7 章 string_reverse.go 中反轉(zhuǎn)數(shù)組的示例)。

您可以將兩個(gè) for 循環(huán)嵌套起來(lái):

for i:=0; i<5; i++ {
    for j:=0; j<10; j++ {
        println(j)
    }
}

如果您使用 for 循環(huán)迭代一個(gè) Unicode 編碼的字符串,會(huì)發(fā)生什么?

示例 5.7 for_string.go

package main

import "fmt"

func main() {
    str := "Go is a beautiful language!"
    fmt.Printf("The length of str is: %d\n", len(str))
    for ix :=0; ix < len(str); ix++ {
        fmt.Printf("Character on position %d is: %c \n", ix, str[ix])
    }
    str2 := "日本語(yǔ)"
    fmt.Printf("The length of str2 is: %d\n", len(str2))
    for ix :=0; ix < len(str2); ix++ {
        fmt.Printf("Character on position %d is: %c \n", ix, str2[ix])
    }
}

輸出:

The length of str is: 27
Character on position 0 is: G 
Character on position 1 is: o 
Character on position 2 is:   
Character on position 3 is: i 
Character on position 4 is: s 
Character on position 5 is:   
Character on position 6 is: a 
Character on position 7 is:   
Character on position 8 is: b 
Character on position 9 is: e 
Character on position 10 is: a 
Character on position 11 is: u 
Character on position 12 is: t 
Character on position 13 is: i 
Character on position 14 is: f 
Character on position 15 is: u 
Character on position 16 is: l 
Character on position 17 is:   
Character on position 18 is: l 
Character on position 19 is: a 
Character on position 20 is: n 
Character on position 21 is: g 
Character on position 22 is: u 
Character on position 23 is: a 
Character on position 24 is: g 
Character on position 25 is: e 
Character on position 26 is: ! 
The length of str2 is: 9
Character on position 0 is: ? 
Character on position 1 is: ? 
Character on position 2 is: ¥ 
Character on position 3 is: ? 
Character on position 4 is: ? 
Character on position 5 is: ? 
Character on position 6 is: è 
Character on position 7 is: a 
Character on position 8 is: ? 

如果我們打印 str 和 str2 的長(zhǎng)度,會(huì)分別得到 27 和 9。

由此我們可以發(fā)現(xiàn),ASCII 編碼的字符占用 1 個(gè)字節(jié),既每個(gè)索引都指向不同的字符,而非 ASCII 編碼的字符(占有 2 到 4 個(gè)字節(jié))不能單純地使用索引來(lái)判斷是否為同一個(gè)字符。我們會(huì)在第 5.4.4 節(jié)解決這個(gè)問(wèn)題。

練習(xí)題

練習(xí) 5.4 for_loop.go

  1. 使用 for 結(jié)構(gòu)創(chuàng)建一個(gè)簡(jiǎn)單的循環(huán)。要求循環(huán) 15 次然后使用 fmt 包來(lái)打印計(jì)數(shù)器的值。
  2. 使用 goto 語(yǔ)句重寫循環(huán),要求不能使用 for 關(guān)鍵字。

練習(xí) 5.5 for_character.go

創(chuàng)建一個(gè)程序,要求能夠打印類似下面的結(jié)果(直到每行 25 個(gè)字符時(shí)為止):

G
GG
GGG
GGGG
GGGGG
GGGGGG
  1. 使用 2 層嵌套 for 循環(huán)。
  2. 使用一層 for 循環(huán)以及字符串截?cái)唷?/li>

練習(xí) 5.6 bitwise_complement.go

使用按位補(bǔ)碼從 0 到 10,使用位表達(dá)式 %b 來(lái)格式化輸出。

練習(xí) 5.7 Fizz-Buzz 問(wèn)題:fizzbuzz.go

寫一個(gè)從 1 打印到 100 的程序,但是每當(dāng)遇到 3 的倍數(shù)時(shí),不打印相應(yīng)的數(shù)字,但打印一次 "Fizz"。遇到 5 的倍數(shù)時(shí),打印 Buzz 而不是相應(yīng)的數(shù)字。對(duì)于同時(shí)為 3 和 5 的倍數(shù)的數(shù),打印 FizzBuzz(提示:使用 switch 語(yǔ)句)。

練習(xí) 5.8 rectangle_stars.go

使用 * 符號(hào)打印寬為 20,高為 10 的矩形。

5.4.2 基于條件判斷的迭代

for 結(jié)構(gòu)的第二種形式是沒(méi)有頭部的條件判斷迭代(類似其它語(yǔ)言中的 while 循環(huán)),基本形式為:for 條件語(yǔ)句 {}

您也可以認(rèn)為這是沒(méi)有初始化語(yǔ)句和修飾語(yǔ)句的 for 結(jié)構(gòu),因此 ;; 便是多余的了。

Listing 5.8 for2.go

package main

import "fmt"

func main() {
    var i int = 5

    for i >= 0 {
        i = i - 1
        fmt.Printf("The variable i is now: %d\n", i)
    }
}

輸出:

The variable i is now: 4
The variable i is now: 3
The variable i is now: 2
The variable i is now: 1
The variable i is now: 0
The variable i is now: -1

5.4.3 無(wú)限循環(huán)

條件語(yǔ)句是可以被省略的,如 i:=0; ; i++for { }for ;; { };; 會(huì)在使用 gofmt 時(shí)被移除):這些循環(huán)的本質(zhì)就是無(wú)限循環(huán)。最后一個(gè)形式也可以被改寫為 for true { },但一般情況下都會(huì)直接寫 for { }。

如果 for 循環(huán)的頭部沒(méi)有條件語(yǔ)句,那么就會(huì)認(rèn)為條件永遠(yuǎn)為 true,因此循環(huán)體內(nèi)必須有相關(guān)的條件判斷以確保會(huì)在某個(gè)時(shí)刻退出循環(huán)。

想要直接退出循環(huán)體,可以使用 break 語(yǔ)句(第 5.5 節(jié))或 return 語(yǔ)句直接返回(第 6.1 節(jié))。

但這兩者之間有所區(qū)別,break 只是退出當(dāng)前的循環(huán)體,而 return 語(yǔ)句提前對(duì)函數(shù)進(jìn)行返回,不會(huì)執(zhí)行后續(xù)的代碼。

無(wú)限循環(huán)的經(jīng)典應(yīng)用是服務(wù)器,用于不斷等待和接受新的請(qǐng)求。

for t, err = p.Token(); err == nil; t, err = p.Token() {
    ...
}

5.4.4 for-range 結(jié)構(gòu)

這是 Go 特有的一種的迭代結(jié)構(gòu),您會(huì)發(fā)現(xiàn)它在許多情況下都非常有用。它可以迭代任何一個(gè)集合(包括數(shù)組和 map,詳見(jiàn)第 7 和 8 章)。語(yǔ)法上很類似其它語(yǔ)言中 foreach 語(yǔ)句,但您依舊可以獲得每次迭代所對(duì)應(yīng)的索引。一般形式為:for ix, val := range coll { }。

要注意的是,val 始終為集合中對(duì)應(yīng)索引的值拷貝,因此它一般只具有只讀性質(zhì),對(duì)它所做的任何修改都不會(huì)影響到集合中原有的值(譯者注:如果 val 為指針,則會(huì)產(chǎn)生指針的拷貝,依舊可以修改集合中的原值)。一個(gè)字符串是 Unicode 編碼的字符(或稱之為 rune)集合,因此您也可以用它迭代字符串:

for pos, char := range str {
...
}

每個(gè) rune 字符和索引在 for-range 循環(huán)中是一一對(duì)應(yīng)的。它能夠自動(dòng)根據(jù) UTF-8 規(guī)則識(shí)別 Unicode 編碼的字符。

示例 5.9 range_string.go

package main

import "fmt"

func main() {
    str := "Go is a beautiful language!"
    fmt.Printf("The length of str is: %d\n", len(str))
    for pos, char := range str {
        fmt.Printf("Character on position %d is: %c \n", pos, char)
    }
    fmt.Println()
    str2 := "Chinese: 日本語(yǔ)"
    fmt.Printf("The length of str2 is: %d\n", len(str2))
    for pos, char := range str2 {
        fmt.Printf("character %c starts at byte position %d\n", char, pos)
    }
    fmt.Println()
    fmt.Println("index int(rune) rune    char bytes")
    for index, rune := range str2 {
        fmt.Printf("%-2d      %d      %U '%c' % X\n", index, rune, rune, rune, []byte(string(rune)))
    }
}

輸出:

The length of str is: 27
Character on position 0 is: G 
Character on position 1 is: o 
Character on position 2 is:   
Character on position 3 is: i 
Character on position 4 is: s 
Character on position 5 is:   
Character on position 6 is: a 
Character on position 7 is:   
Character on position 8 is: b 
Character on position 9 is: e 
Character on position 10 is: a 
Character on position 11 is: u 
Character on position 12 is: t 
Character on position 13 is: i 
Character on position 14 is: f 
Character on position 15 is: u 
Character on position 16 is: l 
Character on position 17 is:   
Character on position 18 is: l 
Character on position 19 is: a 
Character on position 20 is: n 
Character on position 21 is: g 
Character on position 22 is: u 
Character on position 23 is: a 
Character on position 24 is: g 
Character on position 25 is: e 
Character on position 26 is: ! 

The length of str2 is: 18
character C starts at byte position 0
character h starts at byte position 1
character i starts at byte position 2
character n starts at byte position 3
character e starts at byte position 4
character s starts at byte position 5
character e starts at byte position 6
character : starts at byte position 7
character   starts at byte position 8
character 日 starts at byte position 9
character 本 starts at byte position 12
character 語(yǔ) starts at byte position 15

index int(rune) rune    char bytes
0       67      U+0043 'C' 43
1       104      U+0068 'h' 68
2       105      U+0069 'i' 69
3       110      U+006E 'n' 6E
4       101      U+0065 'e' 65
5       115      U+0073 's' 73
6       101      U+0065 'e' 65
7       58      U+003A ':' 3A
8       32      U+0020 ' ' 20
9       26085      U+65E5 '日' E6 97 A5
12      26412      U+672C '本' E6 9C AC
15      35486      U+8A9E '語(yǔ)' E8 AA 9E

請(qǐng)將輸出結(jié)果和 Listing 5.7(for_string.go)進(jìn)行對(duì)比。

我們可以看到,常用英文字符使用 1 個(gè)字節(jié)表示,而漢字(譯者注:嚴(yán)格來(lái)說(shuō),“Chinese: 日本語(yǔ)”的Chinese應(yīng)該是Japanese)使用 3 個(gè)字符表示。

練習(xí) 5.9 以下程序的輸出結(jié)果是什么?

for i := 0; i < 5; i++ {
    var v int
    fmt.Printf("%d ", v)
    v = 5
}

問(wèn)題 5.2: 請(qǐng)描述以下 for 循環(huán)的輸出結(jié)果:

1.

for i := 0; ; i++ {
    fmt.Println("Value of i is now:", i)
}

2.

for i := 0; i < 3; {
    fmt.Println("Value of i:", i)
}

3.

s := ""
for ; s != "aaaaa"; {
    fmt.Println("Value of s:", s)
    s = s + "a"
}

4.

for i, j, s := 0, 5, "a"; i < 3 && j < 100 && s != "aaaaa"; i, j,
    s = i+1, j+1, s + "a" {
    fmt.Println("Value of i, j, s:", i, j, s)
}

鏈接