## 5.6\. 控制流
Go語言的控制結構與C的基本相同但是有些地方還是不同。Go中沒有do, while這樣的循環,for與switch 也非常的靈活。if和switch可以有一個初始化語句 就像for一樣。還增加了一個type switch(類型選擇)和多通道復用(multiway communications multiplexer)的select. 語法有一點點區別,圓括號大部分是 不需要的但是大括號必須始終括號分隔.
### 5.6.1\. If
Go中簡單的if實例:
```
if x > 0 {
return y
}
```
建議在寫if語句的時候采用多行。這是一種非常好的編程風格, 特別是在控制結構體里面有return或break的時候.
if和switch允許初始化聲明,就可以使用本地變量(local variable).
```
if err := file.Chmod(0664); err != nil {
log.Stderr(err)
return err
}
```
在Go的庫文件中,你可能經常看到if語句不進入下一條語句是因為函數在 break,continue,goto或reurn結束, else可以省略。
```
f, err := os.Open(name, os.O_RDONLY, 0)
if err != nil {
return err
}
codeUsing(f)
```
一般的代碼都會考慮錯誤的處理,如果沒有出錯的情況就繼續運行但是在出錯的時候 函數就會返回,所以在這里不需要else語句。
```
f, err := os.Open(name, os.O_RDONLY, 0)
if err != nil {
return err
}
d, err := f.Stat()
if err != nil {
return err
}
codeUsing(f, d)
```
### 5.6.2\. For
Go中的for循環與C相似,但是也有不同的地方。Go只有for和 while, 沒有do-while語句。這里有三種方式,只有一種方式 使用了分號。
```
// Like a C for
for init; condition; post { }
// Like a C while
for condition { }
// Like a C for(;;)
for { }
```
短聲明使得在循環里聲明下標變量很容易。
```
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
```
如果你要遍歷一個array, slice, string or map or 從通道(channel)讀數 range將是你最好的選擇。
```
var m map[string]int
sum := 0
for _, value := range m { // key is unused
sum += value
}
```
對于字符串,range能為你更好的工作,比如解析UTF-8并單獨輸出Unicode字符.
```
for pos, char := range "日本語" {
fmt.Printf("character %c starts at byte position %d\n", char, pos)
}
```
打印出:
```
character 日 starts at byte position 0
character 本 starts at byte position 3
character 語 starts at byte position 6
```
最后,Go中沒有逗號運算符(comma operator)和++與--運算, 如果你想執行多個變量在for語句中,你可以使用并行參數(parallel assignment).
```
// Reverse a
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
```
### 5.6.3\. Switch
Go中的switch要比C更全面,C的表達式僅僅只有常數或整數。 每個分支(cases)從上到下進行匹配取值, 如果switch沒有表達式 那么switches是真。所有才有可能使用switch替換
```
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
```
沒有自動掉到下一分支,但分支可以是逗號分隔的列表:
```
func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}
```
這個操作數組的程序和上面的相似是通過兩個switch語句。
```
// Compare returns an integer comparing the two byte arrays
// lexicographically.
// The result will be 0 if a == b, -1 if a < b, and +1 if a > b
func Compare(a, b []byte) int {
for i := 0; i < len(a) && i < len(b); i++ {
switch {
case a[i] > b[i]:
return 1
case a[i] < b[i]:
return -1
}
}
switch {
case len(a) < len(b):
return -1
case len(a) > len(b):
return 1
}
return 0
}
```
switch可以動態的取得接口變量的數據類型,比如: type switch就是 用關鍵字type插入到接口類型后面的括號來判斷類型, 如果switch 在表達式中聲明了一個變量,在分支上就有相應的類型。
```
switch t := interfaceValue.(type) {
default:
fmt.Printf("unexpected type %T", t) // %T prints type
case bool:
fmt.Printf("boolean %t\n", t)
case int:
fmt.Printf("integer %d\n", t)
case *bool:
fmt.Printf("pointer to boolean %t\n", *t)
case *int:
fmt.Printf("pointer to integer %d\n", *t)
}
```
- 1. 關于本文
- 2. Go語言簡介
- 3. 安裝go環境
- 3.1. 簡介
- 3.2. 安裝C語言工具
- 3.3. 安裝Mercurial
- 3.4. 獲取代碼
- 3.5. 安裝Go
- 3.6. 編寫程序
- 3.7. 進一步學習
- 3.8. 更新go到新版本
- 3.9. 社區資源
- 3.10. 環境變量
- 4. Go語言入門
- 4.1. 簡介
- 4.2. Hello,世界
- 4.3. 分號(Semicolons)
- 4.4. 編譯
- 4.5. Echo
- 4.6. 類型簡介
- 4.7. 申請內存
- 4.8. 常量
- 4.9. I/O包
- 4.10. Rotting cats
- 4.11. Sorting
- 4.12. 打印輸出
- 4.13. 生成素數
- 4.14. Multiplexing
- 5. Effective Go
- 5.1. 簡介
- 5.2. 格式化
- 5.3. 注釋
- 5.4. 命名
- 5.5. 分號
- 5.6. 控制流
- 5.7. 函數
- 5.8. 數據
- 5.9. 初始化
- 5.10. 方法
- 5.11. 接口和其他類型
- 5.12. 內置
- 5.13. 并發
- 5.14. 錯誤處理
- 5.15. Web服務器
- 6. 如何編寫Go程序
- 6.1. 簡介
- 6.2. 社區資源
- 6.3. 新建一個包
- 6.4. 測試
- 6.5. 一個帶測試的演示包
- 7. Codelab: 編寫Web程序
- 7.1. 簡介
- 7.2. 開始
- 7.3. 數據結構
- 7.4. 使用http包
- 7.5. 基于http提供wiki頁面
- 7.6. 編輯頁面
- 7.7. template包
- 7.8. 處理不存在的頁面
- 7.9. 儲存頁面
- 7.10. 錯誤處理
- 7.11. 模板緩存
- 7.12. 驗證
- 7.13. 函數文本和閉包
- 7.14. 試試!
- 7.15. 其他任務
- 8. 針對C++程序員指南
- 8.1. 概念差異
- 8.2. 語法
- 8.3. 常量
- 8.4. Slices(切片)
- 8.5. 構造值對象
- 8.6. Interfaces(接口)
- 8.7. Goroutines
- 8.8. Channels(管道)
- 9. 內存模型
- 9.1. 簡介
- 9.2. Happens Before
- 9.3. 同步(Synchronization)
- 9.4. 錯誤的同步方式
- 10. 附錄
- 10.1. 命令行工具
- 10.2. 視頻和講座
- 10.3. Release History
- 10.4. Go Roadmap
- 10.5. 相關資源