Skip to content

Commit

Permalink
fix: fix a lot of incorrect links (#849)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rethan authored Jun 25, 2022
1 parent 8f1ca57 commit 7a54d34
Show file tree
Hide file tree
Showing 28 changed files with 69 additions and 69 deletions.
2 changes: 1 addition & 1 deletion eBook/04.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func main() {

在 Go 的安装文件里包含了一些可以直接使用的包,即标准库。在 Windows 下,标准库的位置在 Go 根目录下的子目录 `pkg\windows_386` 中;在 Linux 下,标准库在 Go 根目录下的子目录 `pkg\linux_amd64` 中(如果是安装的是 32 位,则在 `linux_386` 目录中)。一般情况下,标准包会存放在 `$GOROOT/pkg/$GOOS_$GOARCH/` 目录下。

Go 的标准库包含了大量的包(如:`fmt``os`),但是你也可以创建自己的包([第 9 章](.\09.0.md))。
Go 的标准库包含了大量的包(如:`fmt``os`),但是你也可以创建自己的包([第 9 章](./09.0.md))。

如果想要构建一个程序,则包和包内的文件都必须以正确的顺序进行编译。包的依赖关系决定了其构建顺序。

Expand Down
2 changes: 1 addition & 1 deletion eBook/04.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const (
)
```

现在,数字 `0``1``2` 分别代表未知性别、女性和男性。这些枚举值可以用于测试某个变量或常量的实际值,比如使用 switch/case 结构([第 5.3 节](.\05.3.md))。
现在,数字 `0``1``2` 分别代表未知性别、女性和男性。这些枚举值可以用于测试某个变量或常量的实际值,比如使用 switch/case 结构([第 5.3 节](./05.3.md))。

在这个例子中,`iota` 可以被用作枚举值:

Expand Down
10 changes: 5 additions & 5 deletions eBook/04.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func main() {

如果你在 Windows 下运行这段代码,则会输出 `The operating system is: windows` 以及相应的环境变量的值;如果你在 Linux 下运行这段代码,则会输出 `The operating system is: linux` 以及相应的的环境变量的值。

这里用到了 `Printf` 的格式化输出的功能([第 4.4.3 节](.\04.4.md))。
这里用到了 `Printf` 的格式化输出的功能([第 4.4.3 节](./04.4.md))。

## 4.4.2 值类型和引用类型

Expand All @@ -146,13 +146,13 @@ func main() {

<img src="images/4.4.2_fig4.1.jpg?raw=true" style="zoom:67%;" />

另外,像数组([第 7 章](.\07.0.md))和结构([第 10 章](.\10.0md))这些复合类型也是值类型。
另外,像数组([第 7 章](./07.0.md))和结构([第 10 章](./10.0md))这些复合类型也是值类型。

当使用等号 `=` 将一个变量的值赋值给另一个变量时,如:`j = i`,实际上是在内存中将 `i` 的值进行了拷贝:

<img src="images/4.4.2_fig4.2.jpg?raw=true" style="zoom: 67%;" />

你可以通过 `&i` 来获取变量 `i` 的内存地址([第 4.9 节](.\04.9.md)),例如:`0xf840000040`(每次的地址都可能不一样)。值类型的变量的值存储在栈中。
你可以通过 `&i` 来获取变量 `i` 的内存地址([第 4.9 节](./04.9.md)),例如:`0xf840000040`(每次的地址都可能不一样)。值类型的变量的值存储在栈中。

内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同。

Expand All @@ -162,15 +162,15 @@ func main() {

<img src="images/4.4.2_fig4.3.jpg?raw=true" style="zoom:67%;" />

这个内存地址被称之为指针(你可以从上图中很清晰地看到,[第 4.9 节](.\04.9.md) 将会详细说明),这个指针实际上也被存在另外的某一个字中。
这个内存地址被称之为指针(你可以从上图中很清晰地看到,[第 4.9 节](./04.9.md) 将会详细说明),这个指针实际上也被存在另外的某一个字中。

同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址。

当使用赋值语句 `r2 = r1` 时,只有引用(地址)被复制。

如果 `r1` 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,`r2` 也会受到影响。

在 Go 语言中,指针([第 4.9 节](.\04.9.md))属于引用类型,其它的引用类型还包括 slices([第 7 章](07.0.md)),maps([第 8 章](08.0.md))和 channel([第 13 章](13.0.md))。被引用的变量会存储在堆中,以便进行垃圾回收,且比栈拥有更大的内存空间。
在 Go 语言中,指针([第 4.9 节](./04.9.md))属于引用类型,其它的引用类型还包括 slices([第 7 章](07.0.md)),maps([第 8 章](08.0.md))和 channel([第 13 章](13.0.md))。被引用的变量会存储在堆中,以便进行垃圾回收,且比栈拥有更大的内存空间。

## 4.4.3 打印

Expand Down
6 changes: 3 additions & 3 deletions eBook/04.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func IntFromFloat64(x float64) int {
}
```

不过如果你实际存的数字超出你要转换到的类型的取值范围的话,则会引发 `panic`[第 13.2 节](.\13.2.md))。
不过如果你实际存的数字超出你要转换到的类型的取值范围的话,则会引发 `panic`[第 13.2 节](./13.2.md))。

**问题 4.1** `int``int64` 是相同的类型吗?

Expand Down Expand Up @@ -468,7 +468,7 @@ func main() {
}
```

实际上,类型别名得到的新类型并非和原类型完全相同,新类型不会拥有原类型所附带的方法([第 10 章](.\10.0.md));`TZ` 可以自定义一个方法用来输出更加人性化的时区信息。
实际上,类型别名得到的新类型并非和原类型完全相同,新类型不会拥有原类型所附带的方法([第 10 章](./10.0.md));`TZ` 可以自定义一个方法用来输出更加人性化的时区信息。

**练习 4.5** 定义一个 `string` 的类型别名 `Rope`,并声明一个该类型的变量。

Expand Down Expand Up @@ -511,7 +511,7 @@ fmt.Printf("%U - %U - %U", ch, ch2, ch3) // UTF-8 code point
41 - 3B2 - 101234
U+0041 - U+03B2 - U+101234

格式化说明符 `%c` 用于表示字符;当和字符配合使用时,`%v``%d` 会输出用于表示该字符的整数;`%U` 输出格式为 `U+hhhh` 的字符串(另一个示例见[第 5.4.4 节](.\05.4.md))。
格式化说明符 `%c` 用于表示字符;当和字符配合使用时,`%v``%d` 会输出用于表示该字符的整数;`%U` 输出格式为 `U+hhhh` 的字符串(另一个示例见[第 5.4.4 节](./05.4.md))。

`unicode` 包含了一些针对测试字符的非常有用的函数(其中 `ch` 代表字符):

Expand Down
2 changes: 1 addition & 1 deletion eBook/04.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fmt.Println(s) //输出 “hello, world!”

在循环中使用加号 `+` 拼接字符串并不是最高效的做法,更好的办法是使用函数 `strings.Join()`[第 4.7.10 节](04.7.md)),有没有更好的办法了?有!使用字节缓冲(`bytes.Buffer`)拼接更加给力([第 7.2.6 节](07.2.md))!

[第 7 章](07.0.md),我们会讲到通过将字符串看作是字节 (`byte`) 的切片 (slice) 来实现对其标准索引法的操作。会在[第 5.4.1 节](05.4.md) 中讲到的 `for` 循环只会根据索引返回字符串中的纯字节,而在[第 5.4.4 节](.\05.4.md)(以及[第 7.6.1 节](07.6.md) 的示例)将会展示如何使用 for-range 循环来实现对 Unicode 字符串的迭代操作。在下一节,我们会学习到许多有关字符串操作的函数和方法,同时 `fmt` 包中的 `fmt.Sprint(x)` 也可以格式化生成并返回你所需要的字符串([第 4.4.3 节](04.3.md))。
[第 7 章](07.0.md),我们会讲到通过将字符串看作是字节 (`byte`) 的切片 (slice) 来实现对其标准索引法的操作。会在[第 5.4.1 节](05.4.md) 中讲到的 `for` 循环只会根据索引返回字符串中的纯字节,而在[第 5.4.4 节](./05.4.md)(以及[第 7.6.1 节](07.6.md) 的示例)将会展示如何使用 for-range 循环来实现对 Unicode 字符串的迭代操作。在下一节,我们会学习到许多有关字符串操作的函数和方法,同时 `fmt` 包中的 `fmt.Sprint(x)` 也可以格式化生成并返回你所需要的字符串([第 4.4.3 节](04.3.md))。

**练习 4.6** [count_characters.go](exercises/chapter_4/count_characters.go)

Expand Down
2 changes: 1 addition & 1 deletion eBook/05.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func main() {

It's equal to 100

在第 12.1 节,我们会使用 `switch` 语句判断从键盘输入的字符(详见[第 12.2 节](12.2.md)[switch.go](.\examples\chapter_12\switch.go))。`switch` 语句的第二种形式是不提供任何被判断的值(实际上默认为判断是否为 `true`),然后在每个 `case` 分支中进行测试不同的条件。当任一分支的测试结果为 `true` 时,该分支的代码会被执行。这看起来非常像链式的 if-else 语句,但是在测试条件非常多的情况下,提供了可读性更好的书写方式。
在第 12.1 节,我们会使用 `switch` 语句判断从键盘输入的字符(详见[第 12.2 节](12.2.md)[switch.go](./examples/chapter_12/switch.go))。`switch` 语句的第二种形式是不提供任何被判断的值(实际上默认为判断是否为 `true`),然后在每个 `case` 分支中进行测试不同的条件。当任一分支的测试结果为 `true` 时,该分支的代码会被执行。这看起来非常像链式的 if-else 语句,但是在测试条件非常多的情况下,提供了可读性更好的书写方式。

```go
switch {
Expand Down
2 changes: 1 addition & 1 deletion eBook/05.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func main() {
for i, j := 0, N; i < j; i, j = i+1, j-1 {}
```

这得益于 Go 语言具有的平行赋值的特性(可以查看[第 7 章](07.0.md) [string_reverse.go](.\examples\chapter_7\string_reverse.go) 中反转数组的示例)。
这得益于 Go 语言具有的平行赋值的特性(可以查看[第 7 章](07.0.md) [string_reverse.go](./examples/chapter_7/string_reverse.go) 中反转数组的示例)。

您可以将两个 for 循环嵌套起来:

Expand Down
2 changes: 1 addition & 1 deletion eBook/05.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func main() {

**特别注意** 使用标签和 `goto` 语句是不被鼓励的:它们会很快导致非常糟糕的程序设计,而且总有更加可读的替代方案来实现相同的需求。

一个建议使用 `goto` 语句的示例会在[第 15.1 章](15.1.md)[simple_tcp_server.go](.\examples\chapter_15\simple_tcp_server.go) 中出现:示例中在发生读取错误时,使用 goto 来跳出无限读取循环并关闭相应的客户端链接。
一个建议使用 `goto` 语句的示例会在[第 15.1 章](15.1.md)[simple_tcp_server.go](./examples/chapter_15/simple_tcp_server.go) 中出现:示例中在发生读取错误时,使用 goto 来跳出无限读取循环并关闭相应的客户端链接。

定义但未使用标签会导致编译错误:`label … defined and not used`

Expand Down
2 changes: 1 addition & 1 deletion eBook/06.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func MultiPly3Nums(a int, b int, c int) int {

`getX2AndX3``getX2AndX3_2` 两个函数演示了如何使用非命名返回值与命名返回值的特性。当需要返回多个非命名返回值时,需要使用 `()` 把它们括起来,比如 `(int, int)`

命名返回值作为结果形参 (result parameters) 被初始化为相应类型的零值,当需要返回的时候,我们只需要一条简单的不带参数的 `return` 语句。需要注意的是,即使只有一个命名返回值,也需要使用 `()` 括起来(参考[第 6.6 节](06.6.md)[fibonacci.go](.\examples\chapter_6\fibonacci.go) 函数)。
命名返回值作为结果形参 (result parameters) 被初始化为相应类型的零值,当需要返回的时候,我们只需要一条简单的不带参数的 `return` 语句。需要注意的是,即使只有一个命名返回值,也需要使用 `()` 括起来(参考[第 6.6 节](06.6.md)[fibonacci.go](./examples/chapter_6/fibonacci.go) 函数)。

示例 6.3 [multiple_return.go](examples/chapter_6/multiple_return.go)

Expand Down
2 changes: 1 addition & 1 deletion eBook/06.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func min(s ...int) int {
The minimum is: 0
The minimum in the slice is: 1

**练习 6.3** [varargs.go](exercises\chapter_6\varargs.go)
**练习 6.3** [varargs.go](exercises/chapter_6/varargs.go)

写一个函数,该函数接受一个变长参数并对每个元素进行换行打印。

Expand Down
6 changes: 3 additions & 3 deletions eBook/06.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ func RevSign(nr int) int {

### 练习题

**练习 6.4** [fibonacci2.go](exercises\chapter_6\fibonacci2.go)
**练习 6.4** [fibonacci2.go](exercises/chapter_6/fibonacci2.go)

重写本节中生成斐波那契数列的程序并返回两个命名返回值(详见[第 6.2 节](06.2.md)),即数列中的位置和对应的值,例如 5 与 4,89 与 10。

**练习 6.5** [10to1_recursive.go](exercises\chapter_6\10to1_recursive.go)
**练习 6.5** [10to1_recursive.go](exercises/chapter_6/10to1_recursive.go)

使用递归函数从 10 打印到 1。

**练习 6.6** [factorial.go](exercises\chapter_6\factorial.go)
**练习 6.6** [factorial.go](exercises/chapter_6/factorial.go)

实现一个输出前 30 个整数的阶乘的程序。

Expand Down
2 changes: 1 addition & 1 deletion eBook/06.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ go func(i int) {

这样闭包函数就能够被应用到整个集合的元素上,并修改它们的值。然后这些变量就可以用于表示或计算全局或平均值。

**练习 6.9** [fibonacci_closure](exercises\chapter_6\fibonacci_closure.go)
**练习 6.9** [fibonacci_closure](exercises/chapter_6/fibonacci_closure.go)

不使用递归但使用闭包改写第 6.6 节中的斐波那契数列程序。

Expand Down
6 changes: 3 additions & 3 deletions eBook/07.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ func main() {

**练习**

练习7.1:[array_value.go](examples\chapter_7\array_value.go):
练习7.1:[array_value.go](examples/chapter_7/array_value.go):

证明当数组赋值时,发生了数组内存拷贝。

练习7.2:[for_array.go](examples\chapter_7\for_array.go):
练习7.2:[for_array.go](examples/chapter_7/for_array.go):

写一个循环并用下标给数组赋值(从 0 到 15)并且将数组打印在屏幕上。

练习7.3:[fibonacci_array.go](examples\chapter_7\fibonacci_array.go):
练习7.3:[fibonacci_array.go](examples/chapter_7/fibonacci_array.go):

[第 6.6 节](06.6.md) 我们看到了一个递归计算 Fibonacci 数值的方法。但是通过数组我们可以更快的计算出 Fibonacci 数。完成该方法并打印出前 50 个 Fibonacci 数字。

Expand Down
12 changes: 6 additions & 6 deletions eBook/07.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,31 +176,31 @@ func FindFileDigits(filename string) []byte {
}
```

**练习 7.12** [split_string.go](exercises\chapter_7\split_string.go)
**练习 7.12** [split_string.go](exercises/chapter_7/split_string.go)

编写一个函数,要求其接受两个参数,原始字符串 `str` 和分割索引 `i`,然后返回两个分割后的字符串。

**练习 7.13** [string_split2.go](exercises\chapter_7\string_split2.go)
**练习 7.13** [string_split2.go](exercises/chapter_7/string_split2.go)

假设有字符串 `str`,那么 `str[len(str)/2:] + str[:len(str)/2]` 的结果是什么?

**练习 7.14** [string_reverse.go](exercises\chapter_7\string_reverse.go)
**练习 7.14** [string_reverse.go](exercises/chapter_7/string_reverse.go)

编写一个程序,要求能够反转字符串,即将 `"Google"` 转换成 `"elgooG"`(提示:使用 `[]byte` 类型的切片)。

如果您使用两个切片来实现反转,请再尝试使用一个切片(提示:使用交换法)。

如果您想要反转 Unicode 编码的字符串,请使用 `[]int32` 类型的切片。

**练习 7.15** [Q29_uniq.go](exercises\chapter_7\uniq.go)
**练习 7.15** [Q29_uniq.go](exercises/chapter_7/uniq.go)

编写一个程序,要求能够遍历一个字符数组,并将当前字符和前一个字符不相同的字符拷贝至另一个数组。

**练习 7.16** [bubblesort.go](exercises\chapter_7\bubblesort.go)
**练习 7.16** [bubblesort.go](exercises/chapter_7/bubblesort.go)

编写一个程序,使用冒泡排序的方法排序一个包含整数的切片(算法的定义可参考 [维基百科](http://en.wikipedia.org/wiki/Bubble_sort))。

**练习 7.17** [map_function.go](exercises\chapter_7\map_function.go)
**练习 7.17** [map_function.go](exercises/chapter_7/map_function.go)

在函数式编程语言中,一个 map-function 是指能够接受一个函数原型和一个列表,并使用列表中的值依次执行函数原型,公式为:`map ( F(), (e1,e2, . . . ,en) ) = ( F(e1), F(e2), ... F(en) )`

Expand Down
2 changes: 1 addition & 1 deletion eBook/08.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ for key := range capitals {
}
```

**练习 8.1** [map_days.go](exercises\chapter_8\map_days.go)
**练习 8.1** [map_days.go](exercises/chapter_8/map_days.go)

创建一个 `map` 来保存每周 7 天的名字,将它们打印出来并且测试是否存在 `"Tuesday"``"Hollyday"`

Expand Down
2 changes: 1 addition & 1 deletion eBook/08.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func main() {

如果原始 value 值不唯一那这么做肯定会出问题;这种情况下不会报错,但是当遇到不唯一的 key 时应当直接停止对调,且此时对调后的 `map` 很可能没有包含原 `map` 的所有键值对!一种解决方法就是仔细检查唯一性并且使用多值 `map`,比如使用 `map[int][]string` 类型。

**练习 8.2** [map_drinks.go](exercises\chapter_8\map_drinks.go)
**练习 8.2** [map_drinks.go](exercises/chapter_8/map_drinks.go)

构造一个将英文饮料名映射为法语(或者任意你的母语)的集合;先打印所有的饮料,然后打印原名和翻译后的名字。接下来按照英文名排序后再打印出来。

Expand Down
4 changes: 2 additions & 2 deletions eBook/09.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ for e := l.Front(); e != nil; e = e.Next() {

`exp` 包中有许多将被编译为新包的实验性的包。在下次稳定版本发布的时候,它们将成为独立的包。如果前一个版本已经存在了,它们将被作为过时的包被回收。然而 Go1.0 发布的时候并没有包含过时或者实验性的包。

**练习 9.1** [Q20_linked_list.go](exercises\chapter_9\dlinked_list.go)
**练习 9.1** [Q20_linked_list.go](exercises/chapter_9/dlinked_list.go)

使用 `container/list` 包实现一个双向链表,将 `101``102``103` 放入其中并打印出来。

**练习 9.2** [size_int.go](exercises\chapter_9\size_int.go)
**练习 9.2** [size_int.go](exercises/chapter_9/size_int.go)

通过使用 `unsafe` 包中的方法来测试你电脑上一个整型变量占用多少个字节。

Expand Down
6 changes: 3 additions & 3 deletions eBook/09.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ a)一个包能分成多个源文件么?

b)一个源文件是否能包含多个包?

**练习 9.3** [main_greetings.go](exercises\chapter_9\main_greetings.go)
**练习 9.3** [main_greetings.go](exercises/chapter_9/main_greetings.go)

创建一个程序 main_greetings.go 能够和用户说 `"Good Day"` 或者 `"Good Night"`。不同的问候应该放到单独的 `greetings` 包中。

在同一个包中创建一个 `IsAM` 函数返回一个布尔值用来判断当前时间是 AM 还是 PM,同样创建 `IsAfternoon``IsEvening` 函数。

使用 main_greetings 作出合适的问候(提示:使用 `time` 包)。

**练习 9.4** 创建一个程序 [main_oddven.go](exercises\chapter_9\main_oddeven.go) 判断前 100 个整数是不是偶数,将判断所用的函数编写在 `even` 包里。
**练习 9.4** 创建一个程序 [main_oddven.go](exercises/chapter_9/main_oddeven.go) 判断前 100 个整数是不是偶数,将判断所用的函数编写在 `even` 包里。

**练习 9.5** 使用[第 6.6 节](06.6.md)的斐波那契程序:

Expand All @@ -169,7 +169,7 @@ b)一个源文件是否能包含多个包?

2)扩展 `fibo` 包将通过调用斐波那契的时候,操作也作为一个参数。实验 `"+"``"*"`

[main_fibo.go](exercises\chapter_9\main_fibo.go) / [fibonacci.go](exercises/chapter_6/fibonacci.go)
[main_fibo.go](exercises/chapter_9/main_fibo.go) / [fibonacci.go](exercises/chapter_6/fibonacci.go)

## 链接

Expand Down
Loading

0 comments on commit 7a54d34

Please sign in to comment.