diff options
Diffstat (limited to 'zh-cn/go-zh.html.markdown')
| -rw-r--r-- | zh-cn/go-zh.html.markdown | 183 | 
1 files changed, 94 insertions, 89 deletions
diff --git a/zh-cn/go-zh.html.markdown b/zh-cn/go-zh.html.markdown index 25fd1f03..8f7cb2af 100644 --- a/zh-cn/go-zh.html.markdown +++ b/zh-cn/go-zh.html.markdown @@ -29,7 +29,8 @@ import (      "strconv"   // 字符串转换  ) -//函数声明:Main是程序执行的入口。不管你喜欢还是不喜欢,反正G就用了花括号来包住函数体。 +// 函数声明:Main是程序执行的入口。 +// 不管你喜欢还是不喜欢,反正G就用了花括号来包住函数体。  func main() {      // 往标准输出打印一行。      // 用包名fmt限制打印函数。 @@ -65,10 +66,10 @@ func learnTypes() {  can include line breaks.` // 同样是String类型      // 非ascii字符。Go使用UTF-8编码。 -	g := 'Σ' // rune类型,uint32的别名,使用UTF-8编码 +    g := 'Σ' // rune类型,uint32的别名,使用UTF-8编码 -	f := 3.14195 // float64类型,IEEE-754 64位浮点数 -	c := 3 + 4i  // complex128类型,内部使用两个float64表示 +    f := 3.14195 // float64类型,IEEE-754 64位浮点数 +    c := 3 + 4i  // complex128类型,内部使用两个float64表示      // Var变量可以直接初始化。      var u uint = 7  // unsigned 无符号变量,但是实现依赖int型变量的长度 @@ -99,9 +100,9 @@ can include line breaks.` // 同样是String类型      // 下划线 _ 可以使你“使用”一个变量,但是丢弃它的值。      _,_,_,_,_,_,_,_,_ = s2, g, f, u, pi, n, a3, s4, bs      // 输出变量 -	fmt.Println(s, c, a4, s3, d2, m) +    fmt.Println(s, c, a4, s3, d2, m) -	learnFlowControl() // 回到流程控制  +    learnFlowControl() // 回到流程控制   }  // Go全面支持垃圾回收。Go有指针,但是不支持指针运算。 @@ -117,155 +118,159 @@ func learnMemory() (p, q *int) {  }  func expensiveComputation() int { -	return 1e6 +    return 1e6  }  func learnFlowControl() {      // If需要花括号,括号就免了 -	if true { -		fmt.Println("told ya") -	} -    // 用go fmt 命令可以帮你格式化代码,所以不用怕被人吐槽代码风格了,也不用容忍被人的代码风格。 -	if false { -		// pout -	} else { -		// gloat -	} +    if true { +        fmt.Println("told ya") +    } +    // 用go fmt 命令可以帮你格式化代码,所以不用怕被人吐槽代码风格了, +    // 也不用容忍被人的代码风格。 +    if false { +        // pout +    } else { +        // gloat +    }      // 如果太多嵌套的if语句,推荐使用switch -	x := 1 -	switch x { -	case 0: -	case 1: +    x := 1 +    switch x { +    case 0: +    case 1:          // 隐式调用break语句,匹配上一个即停止 -	case 2: +    case 2:          // 不会运行 -	} +    }      // 和if一样,for也不用括号 -	for x := 0; x < 3; x++ { // ++ 自增 -		fmt.Println("iteration", x) -	} +    for x := 0; x < 3; x++ { // ++ 自增 +        fmt.Println("iteration", x) +    }      // x在这里还是1。为什么?      // for 是go里唯一的循环关键字,不过它有很多变种 -	for { // 无限循环 -		break    // 骗你的  -		continue // 不会运行的 -	} +    for { // 无限循环 +        break    // 骗你的  +        continue // 不会运行的 +    }      // 和for一样,if中的:=先给y赋值,然后再和x作比较。 -	if y := expensiveComputation(); y > x { -		x = y -	} +    if y := expensiveComputation(); y > x { +        x = y +    }      // 闭包函数 -	xBig := func() bool { -		return x > 100 // x是上面声明的变量引用 -	} -	fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)  -	x /= 1e5                     // x变成10 -	fmt.Println("xBig:", xBig()) // 现在是false +    xBig := func() bool { +        return x > 100 // x是上面声明的变量引用 +    } +    fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)  +    x /= 1e5                     // x变成10 +    fmt.Println("xBig:", xBig()) // 现在是false      // 当你需要goto的时候,你会爱死它的! -	goto love +    goto love  love: -	learnInterfaces() // 好东西来了! +    learnInterfaces() // 好东西来了!  }  // 定义Stringer为一个接口类型,有一个方法String  type Stringer interface { -	String() string +    String() string  }  // 定义pair为一个结构体,有x和y两个int型变量。  type pair struct { -	x, y int +    x, y int  }  // 定义pair类型的方法,实现Stringer接口。  func (p pair) String() string { // p被叫做“接收器”      // Sprintf是fmt包中的另一个公有函数。      // 用 . 调用p中的元素。 -	return fmt.Sprintf("(%d, %d)", p.x, p.y) +    return fmt.Sprintf("(%d, %d)", p.x, p.y)  }  func learnInterfaces() {      // 花括号用来定义结构体变量,:=在这里将一个结构体变量赋值给p。 -	p := pair{3, 4} -	fmt.Println(p.String()) // 调用pair类型p的String方法  -	var i Stringer          // 声明i为Stringer接口类型  -	i = p                   // 有效!因为p实现了Stringer接口(类似java中的塑型)  +    p := pair{3, 4} +    fmt.Println(p.String()) // 调用pair类型p的String方法  +    var i Stringer          // 声明i为Stringer接口类型  +    i = p                   // 有效!因为p实现了Stringer接口(类似java中的塑型)       // 调用i的String方法,输出和上面一样 -	fmt.Println(i.String()) +    fmt.Println(i.String()) -    // fmt包中的Println函数向对象要它们的string输出,实现了String方法就可以这样使用了。(类似java中的序列化) -	fmt.Println(p) // 输出和上面一样,自动调用String函数。 -	fmt.Println(i) // 输出和上面一样。 +    // fmt包中的Println函数向对象要它们的string输出,实现了String方法就可以这样使用了。 +    // (类似java中的序列化) +    fmt.Println(p) // 输出和上面一样,自动调用String函数。 +    fmt.Println(i) // 输出和上面一样。 -	learnErrorHandling() +    learnErrorHandling()  }  func learnErrorHandling() { -	// ", ok"用来判断有没有正常工作  -	m := map[int]string{3: "three", 4: "four"} -	if x, ok := m[1]; !ok { // ok 为false,因为m中没有1 -		fmt.Println("no one there") -	} else { -		fmt.Print(x) // 如果x在map中的话,x就是那个值喽。 -	} +    // ", ok"用来判断有没有正常工作  +    m := map[int]string{3: "three", 4: "four"} +    if x, ok := m[1]; !ok { // ok 为false,因为m中没有1 +        fmt.Println("no one there") +    } else { +        fmt.Print(x) // 如果x在map中的话,x就是那个值喽。 +    }      // 错误可不只是ok,它还可以给出关于问题的更多细节。 -	if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value -		// 输出"strconv.ParseInt: parsing "non-int": invalid syntax" -		fmt.Println(err) -	} +    if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value +        // 输出"strconv.ParseInt: parsing "non-int": invalid syntax" +        fmt.Println(err) +    }      // 待会再说接口吧。同时, -	learnConcurrency() +    learnConcurrency()  }  // c是channel类型,一个并发安全的通信对象。  func inc(i int, c chan int) { -	c <- i + 1 // <-把右边的发送到左边的channel。 +    c <- i + 1 // <-把右边的发送到左边的channel。  }  // 我们将用inc函数来并发地增加一些数字。  func learnConcurrency() {      // 用make来声明一个slice,make会分配和初始化slice,map和channel。 -	c := make(chan int) -    // 用go关键字开始三个并发的goroutine,如果机器支持的话,还可能是并行执行。三个都被发送到同一个channel。 -	go inc(0, c) // go is a statement that starts a new goroutine. -	go inc(10, c) -	go inc(-805, c) +    c := make(chan int) +    // 用go关键字开始三个并发的goroutine,如果机器支持的话,还可能是并行执行。 +    // 三个都被发送到同一个channel。 +    go inc(0, c) // go is a statement that starts a new goroutine. +    go inc(10, c) +    go inc(-805, c)      // 从channel中独处结果并打印。      // 打印出什么东西是不可预知的。 -	fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是接收操作。 - -	cs := make(chan string)       // 操作string的channel -	cc := make(chan chan string)  // 操作channel的channel -	go func() { c <- 84 }()       // 开始一个goroutine来发送一个新的数字  -	go func() { cs <- "wordy" }() // 发送给cs -    // Select类似于switch,但是每个case包括一个channel操作。它随机选择一个准备好通讯的case。 -	select { -	case i := <-c: // 从channel接收的值可以赋给其他变量 -		fmt.Println("it's a", i) -	case <-cs: // 或者直接丢弃 -		fmt.Println("it's a string") -	case <-cc: // 空的,还没作好通讯的准备  -		fmt.Println("didn't happen.") -	} +    fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是接收操作。 + +    cs := make(chan string)       // 操作string的channel +    cc := make(chan chan string)  // 操作channel的channel +    go func() { c <- 84 }()       // 开始一个goroutine来发送一个新的数字  +    go func() { cs <- "wordy" }() // 发送给cs +    // Select类似于switch,但是每个case包括一个channel操作。 +    // 它随机选择一个准备好通讯的case。 +    select { +    case i := <-c: // 从channel接收的值可以赋给其他变量 +        fmt.Println("it's a", i) +    case <-cs: // 或者直接丢弃 +        fmt.Println("it's a string") +    case <-cc: // 空的,还没作好通讯的准备  +        fmt.Println("didn't happen.") +    }      // 上面c或者cs的值被取到,其中一个goroutine结束,另外一个保持阻塞。 -	learnWebProgramming() // Go很适合web编程,我知道你也想学! +    learnWebProgramming() // Go很适合web编程,我知道你也想学!  }  // http包中的一个简单的函数就可以开启web服务器。  func learnWebProgramming() {      // ListenAndServe第一个参数指定了监听端口,第二个参数是一个接口,特定是http.Handler。 -	err := http.ListenAndServe(":8080", pair{}) -	fmt.Println(err) // 不要无视错误。 +    err := http.ListenAndServe(":8080", pair{}) +    fmt.Println(err) // 不要无视错误。  }  // 使pair实现http.Handler接口的ServeHTTP方法。  func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {      // 使用http.ResponseWriter返回数据 -	w.Write([]byte("You learned Go in Y minutes!")) +    w.Write([]byte("You learned Go in Y minutes!"))  }  ```  | 
