Merge pull request #188 from CrazySssst/master

修改slice的翻译(已处理冲突)
pull/1/head
chai2010 2016-01-08 19:32:32 +08:00
commit d0fa50aa12
2 changed files with 69 additions and 4 deletions

View File

@ -101,7 +101,7 @@ visitAll := func(items []string) {
}
```
在topsort中首先對prereqs中的key排序再調用visitAll。因爲prereqs映射的是數組而不是更複雜的map所以數據的遍歷次序是固定的這意味着你每次運行topsort得到的輸出都是一樣的。 topsort的輸出結果如下:
在topsort中首先對prereqs中的key排序再調用visitAll。因爲prereqs映射的是切片而不是更複雜的map所以數據的遍歷次序是固定的這意味着你每次運行topsort得到的輸出都是一樣的。 topsort的輸出結果如下:
```
1: intro to programming
@ -119,7 +119,7 @@ visitAll := func(items []string) {
13: programming languages
```
讓我們迴到findLinks這個例子。我們將代碼移動到了links包下將函數重命名爲Extract在第八章我們會再次用到這個函數。新的匿名函數被引入用於替換原來的visit函數。該匿名函數負責將新連接添加到數組中。在Extract中使用forEachNode遍歷HTML頁面由於Extract隻需要在遍歷結點前操作結點所以forEachNode的post參數被傳入nil。
讓我們迴到findLinks這個例子。我們將代碼移動到了links包下將函數重命名爲Extract在第八章我們會再次用到這個函數。新的匿名函數被引入用於替換原來的visit函數。該匿名函數負責將新連接添加到切片中。在Extract中使用forEachNode遍歷HTML頁面由於Extract隻需要在遍歷結點前操作結點所以forEachNode的post參數被傳入nil。
```Go
gopl.io/ch5/links
@ -234,7 +234,7 @@ http://research.swtch.com/gotour
當所有發現的鏈接都已經被訪問或電腦的內存耗盡時,程序運行結束。
**練習5.10** 重寫topoSort函數用map代替數組併移除對key的排序代碼。驗證結果的正確性結果不唯一
**練習5.10** 重寫topoSort函數用map代替切片併移除對key的排序代碼。驗證結果的正確性結果不唯一
**練習5.11** 現在線性代數的老師把微積分設爲了前置課程。完善topSort使其能檢測有向圖中的環。

View File

@ -1,3 +1,68 @@
## 5.7. 可變參數
TODO
參數數量可變的函數稱爲爲可變參數函數。典型的例子就是fmt.Printf和類似函數。Printf首先接收一個的必備參數之後接收任意個數的後續參數。
在聲明可變參數函數時,需要在參數列表的最後一個參數類型之前加上省略符號“...”,這表示該函數會接收任意數量的該類型參數。
```Go
gopl.io/ch5/sum
func sum(vals...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
```
sum函數返迴任意個int型參數的和。在函數體中,vals被看作是類型爲[] int的切片。sum可以接收任意數量的int型參數
```Go
fmt.Println(sum()) // "0"
fmt.Println(sum(3)) // "3"
fmt.Println(sum(1, 2, 3, 4)) // "10"
```
在上面的代碼中調用者隱式的創建一個數組併將原始參數複製到數組中再把數組的一個切片作爲參數傳給被調函數。如果原始參數已經是切片類型我們該如何傳遞給sum隻需在最後一個參數後加上省略符。下面的代碼功能與上個例子中最後一條語句相同。
```Go
values := []int{1, 2, 3, 4}
fmt.Println(sum(values...)) // "10"
```
雖然在可變參數函數內部,...int 型參數的行爲看起來很像切片類型,但實際上,可變參數函數和以切片作爲參數的函數是不同的。
```Go
func f(...int) {}
func g([]int) {}
fmt.Printf("%T\n", f) // "func(...int)"
fmt.Printf("%T\n", g) // "func([]int)"
```
可變參數函數經常被用於格式化字符串。下面的errorf函數構造了一個以行號開頭的經過格式化的錯誤信息。函數名的後綴f是一種通用的命名規范代表該可變參數函數可以接收Printf風格的格式化字符串。
```Go
func errorf(linenum int, format string, args...interface{})
{
fmt.Fprintf(os.Stderr, "Line %d: ", linenum)
fmt.Fprintf(os.Stderr, format, args…)
fmt.Fprintln(os.Stderr)
}
linenum, name := 12, "count"
errorf(linenum, "undefined: %s", name) // "Line 12:
undefined: count"
```
interfac{}表示函數的最後一個參數可以接收任意類型我們會在第7章詳細介紹。
**練習5.15** 編寫類似sum的可變參數函數max和min。考慮不傳參時max和min該如何處理再編寫至少接收1個參數的版本。
**練習5.16**編寫多參數版本的strings.Join。
**練習5.17**編寫多參數版本的ElementsByTagName函數接收一個HTML結點樹以及任意數量的標籤名返迴與這些標籤名匹配的所有元素。下面給出了2個例子
```Go
func ElementsByTagName(doc *html.Node, name...string)
[]*html.Node
images := ElementsByTagName(doc, "img")
headings := ElementsByTagName(doc, "h1", "h2", "h3", "h4")
```