mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-12-26 06:46:27 +00:00
ch4: fix code path
This commit is contained in:
parent
ca0f87fad9
commit
3666d2f0e8
@ -80,9 +80,8 @@ fmt.Println(a == d) // compile error: cannot compare [2]int == [3]int
|
|||||||
|
|
||||||
作爲一個眞實的例子,crypto/sha256包的Sum256函數對一個任意的字節slice類型的數據生成一個對應的消息摘要。消息摘要有256bit大小,因此對應[32]byte數組類型。如果兩個消息摘要是相同的,那麽可以認爲兩個消息本身也是相同(譯註:理論上有HASH碼碰撞的情況,但是實際應用可以基本忽略);如果消息摘要不同,那麽消息本身必然也是不同的。下面的例子用SHA256算法分别生成“x”和“X”兩個信息的摘要:
|
作爲一個眞實的例子,crypto/sha256包的Sum256函數對一個任意的字節slice類型的數據生成一個對應的消息摘要。消息摘要有256bit大小,因此對應[32]byte數組類型。如果兩個消息摘要是相同的,那麽可以認爲兩個消息本身也是相同(譯註:理論上有HASH碼碰撞的情況,但是實際應用可以基本忽略);如果消息摘要不同,那麽消息本身必然也是不同的。下面的例子用SHA256算法分别生成“x”和“X”兩個信息的摘要:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/sha256</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/sha256
|
|
||||||
|
|
||||||
import "crypto/sha256"
|
import "crypto/sha256"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -14,9 +14,8 @@ fmt.Printf("%q\n", runes) // "['H' 'e' 'l' 'l' 'o' ',' ' ' '世' '界']"
|
|||||||
|
|
||||||
append函數對於理解slice底層是如何工作的非常重要,所以讓我們仔細査看究竟是發生了什麽。下面是第一個版本的appendInt函數,專門用於處理[]int類型的slice:
|
append函數對於理解slice底層是如何工作的非常重要,所以讓我們仔細査看究竟是發生了什麽。下面是第一個版本的appendInt函數,專門用於處理[]int類型的slice:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/append</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/append
|
|
||||||
|
|
||||||
func appendInt(x []int, y int) []int {
|
func appendInt(x []int, y int) []int {
|
||||||
var z []int
|
var z []int
|
||||||
zlen := len(x) + 1
|
zlen := len(x) + 1
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
讓我們看看更多的例子,比如镟轉slice、反轉slice或在slice原有內存空間脩改元素。給定一個字符串列表,下面的nonempty函數將在原有slice內存空間之上返迴不包含空字符串的列表:
|
讓我們看看更多的例子,比如镟轉slice、反轉slice或在slice原有內存空間脩改元素。給定一個字符串列表,下面的nonempty函數將在原有slice內存空間之上返迴不包含空字符串的列表:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/nonempty</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/nonempty
|
|
||||||
|
|
||||||
// Nonempty is an example of an in-place slice algorithm.
|
// Nonempty is an example of an in-place slice algorithm.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -48,9 +48,8 @@ fmt.Println(endlessSummer) // "[June July August September October]"
|
|||||||
|
|
||||||
因爲slice值包含指向第一個slice元素的指針,因此向函數傳遞slice將允許在函數內部脩改底層數組的元素。換句話説,複製一個slice隻是對底層的數組創建了一個新的slice别名(§2.3.2)。下面的reverse函數在原內存空間將[]int類型的slice反轉,而且它可以用於任意長度的slice。
|
因爲slice值包含指向第一個slice元素的指針,因此向函數傳遞slice將允許在函數內部脩改底層數組的元素。換句話説,複製一個slice隻是對底層的數組創建了一個新的slice别名(§2.3.2)。下面的reverse函數在原內存空間將[]int類型的slice反轉,而且它可以用於任意長度的slice。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/rev</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/rev
|
|
||||||
|
|
||||||
// reverse reverses a slice of ints in place.
|
// reverse reverses a slice of ints in place.
|
||||||
func reverse(s []int) {
|
func reverse(s []int) {
|
||||||
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
@ -155,9 +155,8 @@ equal(map[string]int{"A": 0}, map[string]int{"B": 42})
|
|||||||
|
|
||||||
Go語言中併沒有提供一個set類型,但是map中的key也是不相同的,可以用map實現類似set的功能。爲了説明這一點,下面的dedup程序讀取多行輸入,但是隻打印第一次出現的行。(它是1.3節中出現的dup程序的變體。)dedup程序通過map來表示所有的輸入行所對應的set集合,以確保已經在集合存在的行不會被重複打印。
|
Go語言中併沒有提供一個set類型,但是map中的key也是不相同的,可以用map實現類似set的功能。爲了説明這一點,下面的dedup程序讀取多行輸入,但是隻打印第一次出現的行。(它是1.3節中出現的dup程序的變體。)dedup程序通過map來表示所有的輸入行所對應的set集合,以確保已經在集合存在的行不會被重複打印。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/dedup</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/dedup
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
seen := make(map[string]bool) // a set of strings
|
seen := make(map[string]bool) // a set of strings
|
||||||
input := bufio.NewScanner(os.Stdin)
|
input := bufio.NewScanner(os.Stdin)
|
||||||
@ -195,9 +194,8 @@ func Count(list []string) int { return m[k(list)] }
|
|||||||
|
|
||||||
這是map的另一個例子,下面的程序用於統計輸入中每個Unicode碼點出現的次數。雖然Unicode全部碼點的數量鉅大,但是出現在特定文檔中的字符種類併沒有多少,使用map可以用比較自然的方式來跟蹤那些出現過字符的次數。
|
這是map的另一個例子,下面的程序用於統計輸入中每個Unicode碼點出現的次數。雖然Unicode全部碼點的數量鉅大,但是出現在特定文檔中的字符種類併沒有多少,使用map可以用比較自然的方式來跟蹤那些出現過字符的次數。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/charcount</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/charcount
|
|
||||||
|
|
||||||
// Charcount computes counts of Unicode characters.
|
// Charcount computes counts of Unicode characters.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -268,9 +266,8 @@ len count
|
|||||||
|
|
||||||
Map的value類型也可以是一個聚合類型,比如是一個map或slice。在下面的代碼中,圖graph的key類型是一個字符串,value類型map[string]bool代表一個字符串集合。從概念上將,graph將一個字符串類型的key映射到一組相關的字符串集合,它們指向新的graph的key。
|
Map的value類型也可以是一個聚合類型,比如是一個map或slice。在下面的代碼中,圖graph的key類型是一個字符串,value類型map[string]bool代表一個字符串集合。從概念上將,graph將一個字符串類型的key映射到一組相關的字符串集合,它們指向新的graph的key。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/graph</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/graph
|
|
||||||
|
|
||||||
var graph = make(map[string]map[string]bool)
|
var graph = make(map[string]map[string]bool)
|
||||||
|
|
||||||
func addEdge(from, to string) {
|
func addEdge(from, to string) {
|
||||||
|
@ -87,9 +87,8 @@ w = Wheel{X: 8, Y: 8, Radius: 5, Spokes: 20} // compile error: unknown fields
|
|||||||
|
|
||||||
結構體字面值必須遵循形狀類型聲明時的結構,所以我們隻能用下面的兩種語法,它們彼此是等價的:
|
結構體字面值必須遵循形狀類型聲明時的結構,所以我們隻能用下面的兩種語法,它們彼此是等價的:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/embed</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/embed
|
|
||||||
|
|
||||||
w = Wheel{Circle{Point{8, 8}, 5}, 20}
|
w = Wheel{Circle{Point{8, 8}, 5}, 20}
|
||||||
|
|
||||||
w = Wheel{
|
w = Wheel{
|
||||||
|
@ -78,9 +78,8 @@ type Employee struct {
|
|||||||
|
|
||||||
一個命名爲S的結構體類型將不能再包含S類型的成員:因爲一個聚合的值不能包含它自身。(該限製同樣適應於數組。)但是S類型的結構體可以包含`*S`指針類型的成員,這可以讓我們創建遞歸的數據結構,比如鏈表和樹結構等。在下面的代碼中,我們使用一個二叉樹來實現一個插入排序:
|
一個命名爲S的結構體類型將不能再包含S類型的成員:因爲一個聚合的值不能包含它自身。(該限製同樣適應於數組。)但是S類型的結構體可以包含`*S`指針類型的成員,這可以讓我們創建遞歸的數據結構,比如鏈表和樹結構等。在下面的代碼中,我們使用一個二叉樹來實現一個插入排序:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/treesort</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/treesort
|
|
||||||
|
|
||||||
type tree struct {
|
type tree struct {
|
||||||
value int
|
value int
|
||||||
left, right *tree
|
left, right *tree
|
||||||
|
@ -22,9 +22,8 @@ object {"year": 1980,
|
|||||||
|
|
||||||
考慮一個應用程序,該程序負責收集各種電影評論併提供反饋功能。它的Movie數據類型和一個典型的表示電影的值列表如下所示。(在結構體聲明中,Year和Color成員後面的字符串面值是結構體成員Tag;我們稍後會解釋它的作用。)
|
考慮一個應用程序,該程序負責收集各種電影評論併提供反饋功能。它的Movie數據類型和一個典型的表示電影的值列表如下所示。(在結構體聲明中,Year和Color成員後面的字符串面值是結構體成員Tag;我們稍後會解釋它的作用。)
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/movie</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/movie
|
|
||||||
|
|
||||||
type Movie struct {
|
type Movie struct {
|
||||||
Title string
|
Title string
|
||||||
Year int `json:"released"`
|
Year int `json:"released"`
|
||||||
@ -127,8 +126,8 @@ fmt.Println(titles) // "[{Casablanca} {Cool Hand Luke} {Bullitt}]"
|
|||||||
|
|
||||||
許多web服務都提供JSON接口,通過HTTP接口發送JSON格式請求併返迴JSON格式的信息。爲了説明這一點,我們通過Github的issue査詢服務來演示類似的用法。首先,我們要定義合適的類型和常量:
|
許多web服務都提供JSON接口,通過HTTP接口發送JSON格式請求併返迴JSON格式的信息。爲了説明這一點,我們通過Github的issue査詢服務來演示類似的用法。首先,我們要定義合適的類型和常量:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/github</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/github
|
|
||||||
// Package github provides a Go API for the GitHub issue tracker.
|
// Package github provides a Go API for the GitHub issue tracker.
|
||||||
// See https://developer.github.com/v3/search/#search-issues.
|
// See https://developer.github.com/v3/search/#search-issues.
|
||||||
package github
|
package github
|
||||||
@ -162,8 +161,8 @@ type User struct {
|
|||||||
|
|
||||||
SearchIssues函數發出一個HTTP請求,然後解碼返迴的JSON格式的結果。因爲用戶提供的査詢條件可能包含類似`?`和`&`之類的特殊字符,爲了避免對URL造成衝突,我們用url.QueryEscape來對査詢中的特殊字符進行轉義操作。
|
SearchIssues函數發出一個HTTP請求,然後解碼返迴的JSON格式的結果。因爲用戶提供的査詢條件可能包含類似`?`和`&`之類的特殊字符,爲了避免對URL造成衝突,我們用url.QueryEscape來對査詢中的特殊字符進行轉義操作。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/github</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/github
|
|
||||||
package github
|
package github
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -203,9 +202,8 @@ func SearchIssues(terms []string) (*IssuesSearchResult, error) {
|
|||||||
|
|
||||||
我們調用Decode方法來填充變量。這里有多種方法可以格式化結構。下面是最簡單的一種,以一個固定寬度打印每個issue,但是在下一節我們將看到如果利用模闆來輸出複雜的格式。
|
我們調用Decode方法來填充變量。這里有多種方法可以格式化結構。下面是最簡單的一種,以一個固定寬度打印每個issue,但是在下一節我們將看到如果利用模闆來輸出複雜的格式。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/issues</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/issues
|
|
||||||
|
|
||||||
// Issues prints a table of GitHub issues matching the search terms.
|
// Issues prints a table of GitHub issues matching the search terms.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/issuesreport</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/issuesreport
|
|
||||||
|
|
||||||
const templ = `{{.TotalCount}} issues:
|
const templ = `{{.TotalCount}} issues:
|
||||||
{{range .Items}}----------------------------------------
|
{{range .Items}}----------------------------------------
|
||||||
Number: {{.Number}}
|
Number: {{.Number}}
|
||||||
@ -89,9 +88,8 @@ Age: 695 days
|
|||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/issueshtml</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/issueshtml
|
|
||||||
|
|
||||||
import "html/template"
|
import "html/template"
|
||||||
|
|
||||||
var issueList = template.Must(template.New("issuelist").Parse(`
|
var issueList = template.Must(template.New("issuelist").Parse(`
|
||||||
@ -142,9 +140,8 @@ $ ./issueshtml repo:golang/go 3133 10535 >issues2.html
|
|||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch4/autoescape</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch4/autoescape
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
const templ = `<p>A: {{.A}}</p><p>B: {{.B}}</p>`
|
const templ = `<p>A: {{.A}}</p><p>B: {{.B}}</p>`
|
||||||
t := template.Must(template.New("escape").Parse(templ))
|
t := template.Must(template.New("escape").Parse(templ))
|
||||||
|
Loading…
Reference in New Issue
Block a user