summaryrefslogtreecommitdiffhomepage
path: root/zh-cn
diff options
context:
space:
mode:
Diffstat (limited to 'zh-cn')
-rw-r--r--zh-cn/go-zh.html.markdown183
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!"))
}
```