diff --git a/README.md b/README.md index 8105444..03ce50e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,25 @@ -### 本书翻译接近完成,欢迎阅读GitBook,提出宝贵的修改意见😘。 -[Mastering_Go_ZH_CN](https://wskdsgcf.gitbook.io/mastering-go-zh-cn) +### 本书已翻译完成,欢迎阅读GitBook,提出宝贵的修改意见😘。 +在线阅读: [Mastering_Go_ZH_CN](https://wskdsgcf.gitbook.io/mastering-go-zh-cn) +PDF下载:移步release中下载PDF,离线阅读 + +英文第二版强势来袭!我们也在招募热爱学习的你,一起来玩转,第二版项目地址:https://github.com/hantmac/Mastering_Go_Second_Edition_Zh_CN # Mastering_Go_ZH_CN ### 《Mastering GO》 -![](https://ws3.sinaimg.cn/large/006tNbRwly1fyma67vtssj30830a074b.jpg) +![](https://tva1.sinaimg.cn/large/00831rSTgy1gcmcnj3re8j304q06mgmo.jpg) ------ +### 交流社区 +有兴趣的读者可加golang交流群,大家一起交流。 + +关注公众号Go_Official_Blog 了解更多官方资讯(公众号中回复`加群`即可)。 +![](https://tva1.sinaimg.cn/large/00831rSTgy1gcmcur033tj306b06b74o.jpg) + +----- 本书适用于Golang程序员。您之前应该阅读有关Go的介绍性书籍,或者已经完成了[Go By Example](https://books.studygolang.com/gobyexample/)。本书的内容包括但不限于并发、网络编程、垃圾回收、组合、GO UNIX系统编程、基本数据类型(Array,Slice,Map)、GO源码、反射,接口,类型方法等高级概念。阅读本书需要一定的编程经验。如果你在工作中使用Go或者业余时间爱好GO,那么这本书一定会让你对GO的理解更上一层楼。 ### 翻译进度 @@ -295,7 +305,6 @@ - [13.11 练习](https://github.com/hantmac/Mastering_Go_ZH_CN/tree/master/eBook/chapter13/13.11.md) - [13.12 本章小结](https://github.com/hantmac/Mastering_Go_ZH_CN/tree/master/eBook/chapter13/13.12.md) ----- -根据翻译进度实时更新。 ======= ------- ### 支持本书 @@ -309,10 +318,6 @@ - 联系邮箱,取得电子版,获得安排的翻译章节,Fork分支,提交PR; - 由多人审核后,合并 -------- -### 交流社区 - - -------- ### 致谢 diff --git a/eBook/chapter10/10.4.3.md b/eBook/chapter10/10.4.3.md index 1fb6057..dbff4a2 100644 --- a/eBook/chapter10/10.4.3.md +++ b/eBook/chapter10/10.4.3.md @@ -24,7 +24,7 @@ func add(c chan int) { select { case input := <-c: sum = sum + input - case <-t.c: + case <-t.C: c = nil fmt.Println(sum) } diff --git a/eBook/chapter10/10.7.1.md b/eBook/chapter10/10.7.1.md index 5a2a0fd..879b921 100644 --- a/eBook/chapter10/10.7.1.md +++ b/eBook/chapter10/10.7.1.md @@ -91,7 +91,7 @@ func connect(c context.Context) error { fmt.Println("Error select:", err) return err } - fmt.Println("Server Response: %s\n", realHTTPData) + fmt.Printf("Server Response: %s\n", realHTTPData) } return nil } @@ -118,7 +118,7 @@ func main() { fmt.Println("Delay:", delay) c := context.Background() - c, cancel := contedxt.WithTimeout(c, time.Duration(delay)*time.Second) + c, cancel := context.WithTimeout(c, time.Duration(delay)*time.Second) defer cancel() fmt.Printf("Connecting to %s \n", myUrl) @@ -199,4 +199,4 @@ Delay: 13 ![""](https://github.com/hantmac/Mastering_Go_ZH_CN/tree/master/images/chapter10/10.7.1.jpg) -这个输出显示只有第三个命令确实从 HTTP 服务器获得了响应——第一和第二个命令都超时了! \ No newline at end of file +这个输出显示只有第三个命令确实从 HTTP 服务器获得了响应——第一和第二个命令都超时了! diff --git a/eBook/chapter10/10.7.2.md b/eBook/chapter10/10.7.2.md index 69a5b76..5e4a9b9 100644 --- a/eBook/chapter10/10.7.2.md +++ b/eBook/chapter10/10.7.2.md @@ -128,7 +128,7 @@ func main() { finished <- true }() makeWP(nWorkers) - fmt.Println(": %v\n", <-finished) + fmt.Printf(": %v\n", <-finished) } ``` @@ -160,4 +160,4 @@ ClientID: 14 int: 14 square:196 当您希望在 `main()` 函数中为每个单独的请求提供服务而不希望得到它的响应时,就像在 `workerpool.go` 中发生的那样,您需要担心的事情就很少了。在 `main()` 函数中既要使用 goroutines 处理请求,又要从它们获得响应,一个简单的办法是使用共享内存或者一个监视进程来搜集数据而不只是打印它们到屏幕上。 -最后,`workerPool.go` 程序的工作是非常的简单,因为 `worker()` 函数不会失败。当您必须在计算机网络上工作或使用其他可能会失败的资源时,情况就不是这样了。 \ No newline at end of file +最后,`workerPool.go` 程序的工作是非常的简单,因为 `worker()` 函数不会失败。当您必须在计算机网络上工作或使用其他可能会失败的资源时,情况就不是这样了。 diff --git a/eBook/chapter2/02.3.1.md b/eBook/chapter2/02.3.1.md index a50c25d..66f5319 100644 --- a/eBook/chapter2/02.3.1.md +++ b/eBook/chapter2/02.3.1.md @@ -23,6 +23,7 @@ go垃圾回收器的操作都是基于**三色算法**,这一章节主要来 堆可以看成许多连接对象的图,如下所示,展示了单独一个垃圾回收的过程。 + ![image](https://raw.githubusercontent.com/hantmac/Mastering_Go_ZH_CN/master/images/chapter2/02.3-1.jpg) @@ -39,7 +40,7 @@ go垃圾回收也可以应用于其它变量例如**channel**!当垃圾回收 Go允许你通过在你的Go代码里放一个```runtime.GC()```的声明来手动去开启一次垃圾回收。但是,要记住一点,```runtime.GC()```会阻塞调用器,并且它可能会阻塞整个程序,尤其是如果你想运行一个非常繁忙的而且有很多对象的go程序。这种情况发生,主要是因为你不能在其他任何事都在频繁变化的时候去处理垃圾回收,因为这种情况不会给垃圾回收器机会,去清楚地确定白色、黑色和灰色集合里的成员。这种垃圾回收状态也被称作是**垃圾回收安全点(garbage collection safe-point)**。 + 你可以在[这里](https://github.com/golang/go/blob/master/src/runtime/mgc.go)找到垃圾回收器相关的高级go代码。你可以学习这个如果你想了解更多关于垃圾回收操作的东西。 ###### *go团队一直在优化垃圾回收器,主要是通过降低垃圾回收器所需要处理三种集合上数据的扫描次数来让它更快。但是尽管进行各种优化,其背后算法的整体原理还是一样的。* - diff --git a/eBook/chapter3/03.4.1.md b/eBook/chapter3/03.4.1.md index e747315..d0f6e05 100644 --- a/eBook/chapter3/03.4.1.md +++ b/eBook/chapter3/03.4.1.md @@ -8,11 +8,11 @@ 然而下面的代码是不能工作的,因为你将`nil`赋值给map: -> aMap := make(string)int{} +> aMap := map[string]int{} > > aMap = nil > -> fmt.println(aMap) +> fmt.Println(aMap) > > aMap["test"] = 1 @@ -22,4 +22,4 @@ > > map[] > -> panic: assiment to entry in nil map \ No newline at end of file +> panic: assiment to entry in nil map diff --git a/eBook/chapter3/03.6.md b/eBook/chapter3/03.6.md index 55b14dd..87146da 100644 --- a/eBook/chapter3/03.6.md +++ b/eBook/chapter3/03.6.md @@ -39,7 +39,7 @@ Go支持指针!**指针**是内存地址,它能够提升代码运行效率 `returnPointer()`的参数是一个整数,返回值是指向整数的指针,尽管这样看起来并没有什么用处,但是在第四章中,当我们讨论指向结构体的指针以及其他复杂数据结构时,你就会发现这种操作的优势。 -`getPointer()`和`returnPointer()`函数的作用都是求一个整数的平凡,区别在于`getPointer()`使用传递来的参数存储计算结果,而`returnPointer()`函数重新声明了一个变量来存储运算结果。 +`getPointer()`和`returnPointer()`函数的作用都是求一个整数的平方,区别在于`getPointer()`使用传递来的参数存储计算结果,而`returnPointer()`函数重新声明了一个变量来存储运算结果。 第二部分: @@ -96,4 +96,4 @@ Go支持指针!**指针**是内存地址,它能够提升代码运行效率 > 144 > 0xc4200140c8 -你可能对`pointers.go`中的某些代码感到困惑,因为我们在第六章才开始讨论函数及函数定义,可以去了解关于函数的更多信息。 \ No newline at end of file +你可能对`pointers.go`中的某些代码感到困惑,因为我们在第六章才开始讨论函数及函数定义,可以去了解关于函数的更多信息。 diff --git a/eBook/chapter3/03.7.md b/eBook/chapter3/03.7.md index 805ae45..5b2aa90 100644 --- a/eBook/chapter3/03.7.md +++ b/eBook/chapter3/03.7.md @@ -1,6 +1,6 @@ # **时间与日期的处理技巧** -本节你将学习到如何加息时间与日期字符串、格式化日期与时间、以你期望的格式打印时间与日期。你可能会觉得这部分内容没有意义,但是当你想要实现多任务同步或者从文本、用户读取日期时,就会发现这一节的作用。 +本节你将学习到如何解析时间与日期字符串、格式化日期与时间、以你期望的格式打印时间与日期。你可能会觉得这部分内容没有意义,但是当你想要实现多任务同步或者从文本、用户读取日期时,就会发现这一节的作用。 Go自带一个处理时间与日期的神器-`time`包,这里将介绍几个实用的函数。 @@ -58,4 +58,4 @@ Go自带一个处理时间与日期的神器-`time`包,这里将介绍几个 > 01 January 2019 > Paris: 2019-01-12 08:59:39.959594352 +0100 CET -现在你应该对`time`包有了一个基本的了解,是时候去深入了解`time`更多的功能了! \ No newline at end of file +现在你应该对`time`包有了一个基本的了解,是时候去深入了解`time`更多的功能了! diff --git a/eBook/chapter5/05.3.md b/eBook/chapter5/05.3.md index d3a4cd2..284a802 100644 --- a/eBook/chapter5/05.3.md +++ b/eBook/chapter5/05.3.md @@ -1,9 +1,9 @@ ### Go 语言中的二叉树 -**二叉树**是每个节点最多有两个两个分支的数据结构。“最多”表示一个节点可以连接一至两个子节点,或者不连接其他子节点。**树的根节点**是树结构中的第一个节点。**树的深度**,又称为树的高度,是从树的根节点到所有节点的路径中最长的一个。而节点的深度是该节点到树的根所经过的路径中边的数量。**叶节点**是没有子节点的节点。 +**二叉树**是每个节点最多有两个分支的数据结构。“最多”表示一个节点可以连接一至两个子节点,或者不连接其他子节点。**树的根节点**是树结构中的第一个节点。**树的深度**,又称为树的高度,是从树的根节点到所有节点的路径中最长的一个。而节点的深度是该节点到树的根所经过的路径中边的数量。**叶节点**是没有子节点的节点。 若一个树的根节点到任意两个叶节点的距离之差不大于 1,则认为这个树是**平衡的**。顾名思义,非平衡树不是平衡的。树的平衡操作困难又缓慢,所以最好从一开始就让你的树保持平衡,而不是在建好树之后再去调整,尤其是这个树有很多节点的时候。 下图是一个非平衡二叉树。它的节根点是 J,叶节点包括 A、G、W 和 D。 -![](../../images/chapter5/05.3-1.jpg) \ No newline at end of file +![](../../images/chapter5/05.3-1.jpg) diff --git a/eBook/chapter8/08.12.md b/eBook/chapter8/08.12.md index 3de4460..c8fef1c 100644 --- a/eBook/chapter8/08.12.md +++ b/eBook/chapter8/08.12.md @@ -29,7 +29,7 @@ func main() { buffer.WriteTo(os.Stdout) ``` -首先,创建一个新的`bytes.Buffer`变量,通过`buffer.Write()`和`fat.Fprintf()`写入数据。然后调用`buffer.WriteTo()`两次。 +首先,创建一个新的`bytes.Buffer`变量,通过`buffer.Write()`和`fmt.Fprintf()`写入数据。然后调用`buffer.WriteTo()`两次。 第一次调用`buffer.WriteTo()`将打印`buffer`的内容。然而,第二次调用`buffer.WriteTo()`将不会有任何输出,因为在第一次调用后,`buffer`内容为空。 diff --git a/eBook/chapter8/08.5.1.md b/eBook/chapter8/08.5.1.md index 655cba3..dfa0948 100644 --- a/eBook/chapter8/08.5.1.md +++ b/eBook/chapter8/08.5.1.md @@ -43,7 +43,7 @@ func lineByLine(file string) error { } ``` -所有的实现都在`lineByLine()`函数中。在确保可以打开指定的文件名进行读取之后,你调用`bufio.NewReader()`创建一个新的读实例,然后你可以调用`bufio.ReadString()`逐行读取文件。行分隔符通过`bufio.ReadString()`参数指定,它指示`bufio.ReadString()`一直读取,直到碰到行分隔符为止。当参数是换行符时,不断调用`bufio.ReadString()`会逐行读取输入文件!注意,使用`fmt.Print()`而不是`fmt.Println()`输出读取行,来显示每个输入行中都包含换行符。 +所有的实现都在`lineByLine()`函数中。在确保可以打开指定的文件名进行读取之后,你调用`bufio.NewReader()`创建一个新的读实例,然后你可以调用`bufio.ReadString()`逐行读取文件。行分隔符通过`bufio.ReadString()`参数指定,它指示`bufio.ReadString()`一直读取,直到碰到行分隔符为止。当参数是换行符时,不断调用`bufio.ReadString()`会逐行读取输入文件!注意,使用`fmt.Print()`而不是`fmt.Println()`输出读取行,说明每个输入行中都包含了换行符。 `byLine.go`第三部分代码如下: diff --git a/eBook/chapter8/08.6.md b/eBook/chapter8/08.6.md index 56ba5c4..7a96db2 100644 --- a/eBook/chapter8/08.6.md +++ b/eBook/chapter8/08.6.md @@ -84,7 +84,7 @@ func main() { } ``` -所以,你需要一直读取输入文件,直接返回错误或者`nil`。 +所以,你需要一直读取输入文件,直到返回错误或者`nil`。 执行`readSize.go`,传入处理的二进制文件,并使用`wc(1)`处理它的输出,来验证程序的正确性。