diff --git a/eBook/04.7.md b/eBook/04.7.md
index 2e7401c..db2f347 100644
--- a/eBook/04.7.md
+++ b/eBook/04.7.md
@@ -273,7 +273,7 @@ func main() {
GO1 - The ABC of Go - 25 -
sl2 joined by ;: GO1;The ABC of Go;25
-其它有关字符串操作的文档请参阅官方文档 [http://golang.org/pkg/strings/](http://golang.org/pkg/strings/)( **译者注:国内用户可访问 [该页面](http://docs.studygolang.com/pkg/strings/)** )。
+其它有关字符串操作的文档请参阅 [官方文档](http://golang.org/pkg/strings/)( **译者注:国内用户可访问 [该页面](http://docs.studygolang.com/pkg/strings/)** )。
## 4.7.11 从字符串中读取内容
@@ -341,7 +341,7 @@ func main() {
在第 5.1 节,我们将会利用 if 语句来对可能出现的错误进行分类处理。
-更多有关该包的讨论,请参阅官方文档 [http://golang.org/pkg/strconv/](http://golang.org/pkg/strconv/)( **译者注:国内用户可访问 [该页面](http://docs.studygolang.com/pkg/strconv/)** )。
+更多有关该包的讨论,请参阅 [官方文档](http://golang.org/pkg/strconv/)( **译者注:国内用户可访问 [该页面](http://docs.studygolang.com/pkg/strconv/)** )。
## 链接
diff --git a/eBook/04.8.md b/eBook/04.8.md
index 7b7eae3..7b32667 100644
--- a/eBook/04.8.md
+++ b/eBook/04.8.md
@@ -9,44 +9,48 @@ Duration 类型表示两个连续时刻所相差的纳秒数,类型为 int64
包中的一个预定义函数 `func (t Time) Format(layout string) string` 可以根据一个格式化字符串来将一个时间 t 转换为相应格式的字符串,你可以使用一些预定义的格式,如:`time.ANSIC` 或 `time.RFC822`。
一般的格式化设计是通过对于一个标准时间的格式化描述来展现的,这听起来很奇怪,但看下面这个例子你就会一目了然:
-
- fmt.Println(t.Format("02 Jan 2006 15:04"))
+
+```go
+fmt.Println(t.Format("02 Jan 2006 15:04"))
+```
输出:
21 Jul 2011 10:31
-其它有关时间操作的文档请参阅官方文档 [http://golang.org/pkg/time/](http://golang.org/pkg/time/)( **译者注:国内用户可访问 [http://docs.studygolang.com/pkg/time/](http://docs.studygolang.com/pkg/time/)** )。
+其它有关时间操作的文档请参阅 [官方文档](http://golang.org/pkg/time/)( **译者注:国内用户可访问 [该页面](http://docs.studygolang.com/pkg/time/)** )。
-Example 4.20 [time.go](examples/chapter_4/time.go)
+示例 4.20 [time.go](examples/chapter_4/time.go)
+
+```go
+package main
+import (
+ "fmt"
+ "time"
+)
- package main
- import (
- "fmt"
- "time"
- )
-
- var week time.Duration
- func main() {
- t := time.Now()
- fmt.Println(t) // e.g. Wed Dec 21 09:52:14 +0100 RST 2011
- fmt.Printf("%02d.%02d.%4d\n", t.Day(), t.Month(), t.Year())
- // 21.12.2011
- t = time.Now().UTC()
- fmt.Println(t) // Wed Dec 21 08:52:14 +0000 UTC 2011
- fmt.Println(time.Now()) // Wed Dec 21 09:52:14 +0100 RST 2011
- // calculating times:
- week = 60 * 60 * 24 * 7 * 1e9 // must be in nanosec
- week_from_now := t.Add(week)
- fmt.Println(week_from_now) // Wed Dec 28 08:52:14 +0000 UTC 2011
- // formatting times:
- fmt.Println(t.Format(time.RFC822)) // 21 Dec 11 0852 UTC
- fmt.Println(t.Format(time.ANSIC)) // Wed Dec 21 08:56:34 2011
- fmt.Println(t.Format("02 Jan 2006 15:04")) // 21 Dec 2011 08:52
- s := t.Format("20060102")
- fmt.Println(t, "=>", s)
- // Wed Dec 21 08:52:14 +0000 UTC 2011 => 20111221
- }
+var week time.Duration
+func main() {
+ t := time.Now()
+ fmt.Println(t) // e.g. Wed Dec 21 09:52:14 +0100 RST 2011
+ fmt.Printf("%02d.%02d.%4d\n", t.Day(), t.Month(), t.Year())
+ // 21.12.2011
+ t = time.Now().UTC()
+ fmt.Println(t) // Wed Dec 21 08:52:14 +0000 UTC 2011
+ fmt.Println(time.Now()) // Wed Dec 21 09:52:14 +0100 RST 2011
+ // calculating times:
+ week = 60 * 60 * 24 * 7 * 1e9 // must be in nanosec
+ week_from_now := t.Add(week)
+ fmt.Println(week_from_now) // Wed Dec 28 08:52:14 +0000 UTC 2011
+ // formatting times:
+ fmt.Println(t.Format(time.RFC822)) // 21 Dec 11 0852 UTC
+ fmt.Println(t.Format(time.ANSIC)) // Wed Dec 21 08:56:34 2011
+ fmt.Println(t.Format("02 Jan 2006 15:04")) // 21 Dec 2011 08:52
+ s := t.Format("20060102")
+ fmt.Println(t, "=>", s)
+ // Wed Dec 21 08:52:14 +0000 UTC 2011 => 20111221
+}
+```
输出的结果已经写在每行 `//` 的后面。
diff --git a/eBook/04.9.md b/eBook/04.9.md
index bda2fc8..32c95c2 100644
--- a/eBook/04.9.md
+++ b/eBook/04.9.md
@@ -8,14 +8,18 @@
Go 语言的取地址符是 `&`,放到一个变量前使用就会返回相应变量的内存地址。
-下面的代码片段(Example 4.9 [pointer.go](examples/chapter_4/pointer.go))可能输出 `An integer: 5, its location in memory: 0x6b0820`(这个值随着你每次运行程序而变化)。
-
- var i1 = 5
- fmt.Printf("An integer: %d, it's location in memory: %p\n", i1, &i1)
+下面的代码片段(示例 4.9 [pointer.go](examples/chapter_4/pointer.go))可能输出 `An integer: 5, its location in memory: 0x6b0820`(这个值随着你每次运行程序而变化)。
+
+```go
+var i1 = 5
+fmt.Printf("An integer: %d, it's location in memory: %p\n", i1, &i1)
+```
这个地址可以存储在一个叫做指针的特殊数据类型中,在本例中这是一个指向 int 的指针,即 `i1`:此处使用 *int 表示。如果我们想调用指针 intP,我们可以这样声明它:
-
- var intP *int
+
+```go
+var intP *int
+```
然后使用 `intP = &i1` 是合法的,此时 intP 指向 i1。
@@ -39,20 +43,22 @@ intP 存储了 i1 的内存地址;它指向了 i1 的位置,它引用了变
现在,我们应当能理解 pointer.go 中的整个程序和他的输出:
-Example 4.21 [pointer.go](examples/chapter_4/pointer.go):
-
- package main
- import "fmt"
- func main() {
- var i1 = 5
- fmt.Printf("An integer: %d, its location in memory: %p\n", i1, &i1)
- var intP *int
- intP = &i1
- fmt.Printf("The value at memory location %p is %d\n", intP, *intP)
- }
+示例 4.21 [pointer.go](examples/chapter_4/pointer.go):
+
+```go
+package main
+import "fmt"
+func main() {
+ var i1 = 5
+ fmt.Printf("An integer: %d, its location in memory: %p\n", i1, &i1)
+ var intP *int
+ intP = &i1
+ fmt.Printf("The value at memory location %p is %d\n", intP, *intP)
+}
+```
输出:
-
+
An integer: 5, its location in memory: 0x24f0820
The value at memory location 0x24f0820 is 5
@@ -64,18 +70,20 @@ Example 4.21 [pointer.go](examples/chapter_4/pointer.go):
它展示了分配一个新的值给 *p 并且更改这个变量自己的值(这里是一个字符串)。
-Example 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
-
- package main
- import "fmt"
- func main() {
- s := "good bye"
- var p *string = &s
- *p = "ciao"
- fmt.Printf("Here is the pointer p: %p\n", p) // prints address
- fmt.Printf("Here is the string *p: %s\n", *p) // prints string
- fmt.Printf("Here is the string s: %s\n", s) // prints same string
- }
+示例 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
+
+```go
+package main
+import "fmt"
+func main() {
+ s := "good bye"
+ var p *string = &s
+ *p = "ciao"
+ fmt.Printf("Here is the pointer p: %p\n", p) // prints address
+ fmt.Printf("Here is the string *p: %s\n", *p) // prints string
+ fmt.Printf("Here is the string s: %s\n", s) // prints same string
+}
+```
输出:
@@ -92,10 +100,12 @@ Example 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
**注意事项**
你不能得到一个文字或常量的地址,例如:
-
- const i = 5
- ptr := &i //error: cannot take the address of i
- ptr2 := &10 //error: cannot take the address of 10
+
+```go
+const i = 5
+ptr := &i //error: cannot take the address of i
+ptr2 := &10 //error: cannot take the address of 10
+```
所以说,Go 语言和 C、C++ 以及 D 语言这些低级(系统)语言一样,都有指针的概念。但是对于经常导致 C 语言内存泄漏继而程序崩溃的指针运算(所谓的指针算法,如:`pointer+2`,移动指针指向字符串的字节数或数组的某个位置)是不被允许的。Go 语言中的指针保证了内存安全,更像是 Java、C# 和 VB.NET 中的引用。
@@ -111,15 +121,17 @@ Example 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go)
对一个空指针的反向引用是不合法的,并且会使程序崩溃:
-Example 4.23 [testcrash.go](examples/chapter_4/testcrash.go):
-
- package main
- func main() {
- var p *int = nil
- *p = 0
- }
- // in Windows: stops only with:
- // runtime error: invalid memory address or nil pointer dereference
+示例 4.23 [testcrash.go](examples/chapter_4/testcrash.go):
+
+```go
+package main
+func main() {
+ var p *int = nil
+ *p = 0
+}
+// in Windows: stops only with:
+// runtime error: invalid memory address or nil pointer dereference
+```
**问题 4.2** 列举 Go 语言中 * 号的所有用法。
diff --git a/eBook/05.0.md b/eBook/05.0.md
index c27fb45..67f9826 100644
--- a/eBook/05.0.md
+++ b/eBook/05.0.md
@@ -2,13 +2,13 @@
到目前为止,我们看到的都是 Go 程序都是从 main() 函数开始执行,然后按顺序执行该函数体中的代码。但我们经常会需要只有在满足一些特定情况时才执行某些代码,也就是说在代码里进行条件判断。针对这种需求,Go 提供了下面这些条件结构和分支结构:
- if-else 结构
- switch 结构
- select 结构,用于 channel 的选择(第 14.4 节)
+- if-else 结构
+- switch 结构
+- elect 结构,用于 channel 的选择(第 14.4 节)
可以使用迭代或循环结构来重复执行一次或多次某段代码(任务):
- for (range) 结构
+- for (range) 结构
一些如 `break` 和 `continue` 这样的关键字可以用于中途改变循环的状态。
diff --git a/eBook/05.1.md b/eBook/05.1.md
index 5ac70db..e6c1eae 100644
--- a/eBook/05.1.md
+++ b/eBook/05.1.md
@@ -2,27 +2,33 @@
if 是用于测试某个条件(布尔型或逻辑型)的语句,如果该条件成立,则会执行 if 后由大括号括起来的代码块,否则就忽略该代码块继续执行后续的代码。
- if condition {
- // do something
- }
+```go
+if condition {
+ // do something
+}
+```
如果存在第二个分支,则可以在上面代码的基础上添加 else 关键字以及另一代码块,这个代码块中的代码只有在条件不满足时才会执行。if 和 else 后的两个代码块是相互独立的分支,只可能执行其中一个。
- if condition {
- // do something
- } else {
- // do something
- }
+```go
+if condition {
+ // do something
+} else {
+ // do something
+}
+```
如果存在第三个分支,则可以使用下面这种三个独立分支的形式:
- if condition1 {
- // do something
- } else if condition2 {
- // do something else
- }else {
- // catch-all or default
- }
+```go
+if condition1 {
+ // do something
+} else if condition2 {
+ // do something else
+}else {
+ // catch-all or default
+}
+```
else-if 分支的数量是没有限制的,但是为了代码的可读性,还是不要在 if 后面加入太多的 else-if 结构。如果你必须使用这种形式,则把尽可能先满足的条件放在前面。
@@ -32,10 +38,12 @@ else-if 分支的数量是没有限制的,但是为了代码的可读性,还
非法的Go代码:
- if x{
- }
- else { // 无效的
- }
+```go
+if x{
+}
+else { // 无效的
+}
+```
要注意的是,在你使用 `gofmt` 格式化代码之后,每个分支内的代码都会缩进 4 个或 8 个空格,或者是 1 个 tab,并且右大括号与对应的 if 关键字垂直对齐。
@@ -43,18 +51,20 @@ else-if 分支的数量是没有限制的,但是为了代码的可读性,还
一种可能用到条件语句的场景是测试变量的值,在不同的情况执行不同的语句,不过将在第 5.3 节讲到的 switch 结构会更适合这种情况。
-Example 5.1 [booleans.go](examples/chapter_5/booleans.go)
+示例 5.1 [booleans.go](examples/chapter_5/booleans.go)
- package main
- import "fmt"
- func main() {
- bool1 := true
- if bool1 {
- fmt.Printf("The value is true\n")
- } else {
- fmt.Printf("The value is false\n")
- }
+```go
+package main
+import "fmt"
+func main() {
+ bool1 := true
+ if bool1 {
+ fmt.Printf("The value is true\n")
+ } else {
+ fmt.Printf("The value is false\n")
}
+}
+```
输出:
@@ -66,22 +76,26 @@ Example 5.1 [booleans.go](examples/chapter_5/booleans.go)
当 if 结构内有 break、continue、goto 或者 return 语句时,Go 代码的常见写法是省略 else 部分(另见第 5.2 节)。无论满足哪个条件都会返回 x 或者 y 时,一般使用以下写法:
- if condition {
- return x
- }
- return y
+```go
+if condition {
+ return x
+}
+return y
+```
-**注意事项** 不要同时在 if-else 结构的两个分支里都使用 return 语句,这将导致编译报错 “function ends without a return statement”(你可以认为这是一个编译器的 Bug 或者特性)。( **译者注:该问题已经在 Go 1.1 中被修复或者说改进** )
+**注意事项** 不要同时在 if-else 结构的两个分支里都使用 return 语句,这将导致编译报错 `function ends without a return statement`(你可以认为这是一个编译器的 Bug 或者特性)。( **译者注:该问题已经在 Go 1.1 中被修复或者说改进** )
这里举一些有用的例子:
-1. 判断一个字符串是否为空:`if str == "" { ... }` 或 `if len(str) == 0 {...}`。
+1. 判断一个字符串是否为空:
+ - `if str == "" { ... }`
+ - `if len(str) == 0 {...}`
2. 判断运行 Go 程序的操作系统类型,这可以通过常量 `runtime.GOOS` 来判断(第 2.2 节)。
-
- if runtime.GOOS == "windows" {
- ...
- } else { // Unix - like
- ...
+
+ if runtime.GOOS == "windows" {
+ . ..
+ } else { // Unix - li ke
+ . ..
}
这段代码一般被放在 init() 函数中执行。这儿还有一段示例来演示如何根据操作系统来决定输入结束的提示:
@@ -116,53 +130,61 @@ Example 5.1 [booleans.go](examples/chapter_5/booleans.go)
在第四种情况中,if 可以包含一个初始化语句(如:给一个变量赋值)。这种写法具有固定的格式(在初始化语句后方必须加上分号):
- if initialization; condition {
- // do something
- }
+```go
+if initialization; condition {
+ // do something
+}
+```
例如:
- val := 10
- if val > max {
- // do something
- }
+```go
+val := 10
+if val > max {
+ // do something
+}
+```
你也可以这样写:
- if val := 10; val > max {
- // do something
- }
+```go
+if val := 10; val > max {
+ // do something
+}
+```
但要注意的是,使用简短方式 `:=` 声明的变量的作用域只存在于 if 结构中(在 if 结构的大括号之间,如果使用 if-else 结构则在 else 代码块中变量也会存在)。如果变量在 if 结构之前就已经存在,那么在 if 结构中,该变量原来的值会被隐藏。最简单的解决方案就是不要在初始化语句中声明变量(见 5.2 节的例 3 了解更多)。
-Example 5.2 [ifelse.go](examples/chapter_5/ifelse.go)
+示例 5.2 [ifelse.go](examples/chapter_5/ifelse.go)
- package main
-
- import "fmt"
-
- func main() {
- var first int = 10
- var cond int
-
- if first <= 0 {
-
- fmt.Printf("first is less than or equal to 0\n")
- } else if first > 0 && first < 5 {
-
- fmt.Printf("first is between 0 and 5\n")
- } else {
-
- fmt.Printf("first is 5 or greater\n")
- }
- if cond = 5; cond > 10 {
-
- fmt.Printf("cond is greater than 10\n")
- } else {
-
- fmt.Printf("cond is not greater than 10\n")
- }
+```go
+package main
+
+import "fmt"
+
+func main() {
+ var first int = 10
+ var cond int
+
+ if first <= 0 {
+
+ fmt.Printf("first is less than or equal to 0\n")
+ } else if first > 0 && first < 5 {
+
+ fmt.Printf("first is between 0 and 5\n")
+ } else {
+
+ fmt.Printf("first is 5 or greater\n")
}
+ if cond = 5; cond > 10 {
+
+ fmt.Printf("cond is greater than 10\n")
+ } else {
+
+ fmt.Printf("cond is not greater than 10\n")
+ }
+}
+```
输出:
@@ -170,11 +192,13 @@ Example 5.2 [ifelse.go](examples/chapter_5/ifelse.go)
下面的代码片段展示了如何通过在初始化语句中获取函数 `process()` 的返回值,并在条件语句中作为判定条件来决定是否执行 if 结构中的代码:
- if value := process(data); value > max {
- ...
- if value := process(data); value > max {
- ...
- }
+```go
+if value := process(data); value > max {
+ ...
+if value := process(data); value > max {
+ ...
+}
+```
## 链接