From 006f81d8e7175c8ea5f24cf4f9a73ce2393fdb8d Mon Sep 17 00:00:00 2001 From: maque Date: Mon, 20 Aug 2018 09:04:48 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E5=B1=82=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0.3.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/0.3.md b/0.3.md index 2a1bb52..8f36914 100644 --- a/0.3.md +++ b/0.3.md @@ -14,14 +14,14 @@ hc@ubt:~$ go get github.com/hyper-carrot/go_lib/logging pkg/ linux_386/ github.com/ - hyper-carrot/ - go_lib/ - logging.a + hyper-carrot/ + go_lib/ + logging.a src/ github.com/ - hyper-carrot/ - go_lib/ - logging/ + hyper-carrot/ + go_lib/ + logging/ ... ``` @@ -212,4 +212,4 @@ WORK=/tmp/go-build636338114 命令`go get`的这一功能是非常有用的。我们的代码在直接或间接依赖某些同时针对多个Go语言版本开发的代码包时,可以自动的检出其正确的版本。也可以说,`go get`命令内置了一定的代码包多版本依赖管理的功能。 -到这里,我向大家介绍了`go get`命令的使用方式。`go get`命令与之前介绍的两个命令一样,是我们编写Go语言程序、构建Go语言项目时必不可少的辅助工具。 \ No newline at end of file +到这里,我向大家介绍了`go get`命令的使用方式。`go get`命令与之前介绍的两个命令一样,是我们编写Go语言程序、构建Go语言项目时必不可少的辅助工具。 From 13fcd7cc41289caf5fbc2730ff61f9777aaf132c Mon Sep 17 00:00:00 2001 From: progyoung Date: Tue, 21 Aug 2018 08:36:35 +0800 Subject: [PATCH 02/17] fix typo --- 0.5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0.5.md b/0.5.md index 0376b1b..51e202e 100644 --- a/0.5.md +++ b/0.5.md @@ -6,8 +6,8 @@ **插播:**所谓Go语言的程序实体,是指变量、常量、函数、结构体以及接口。而程序实体的标识符即是代表它们的名称。标识符又分非限定标识符和限定标识符。其中,限定标识符一般用于表示某个代码包中的程序实体或者某个结构体类型中的方法或字段。例如,标准库代码包`io`中的名为`EOF`的变量用限定标识符表示即`io.EOF`。又例如,如果我有一个`sync.WaitGroup`类型的变量`wg`并且想调用它的`Add`方法,那么可以这样写`wg.Add()`。其中,`wg.Add`就是一个限定标识符,而后面的`()`则代表了调用操作。 -下面说明怎样使用`go doc`命令。先来看一下`go doc`命令课结束的标记。 - +下面说明怎样使用`go doc`命令。先来看一下`go doc`命令可接受的标记。 + _表0-5 ```go doc```命令的标记说明_ 标记名称 | 标记描述 From 88ed32d3f4e7d1882184265a5cf4560f4475bcd1 Mon Sep 17 00:00:00 2001 From: invzhi Date: Tue, 11 Sep 2018 18:31:59 +0800 Subject: [PATCH 03/17] Fix typo: 'vsc' -> 'vcs' --- 0.3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0.3.md b/0.3.md index 8f36914..1125a1c 100644 --- a/0.3.md +++ b/0.3.md @@ -101,7 +101,7 @@ hypermind.cn /talon/analyzer // 导入注释中的导入路径 ``` -实际上,`content`属性中的`import-prefix`的位置上应该填入我们自定义的远程代码包导入路径的前缀。这个前缀应该与我们的处理程序关联的那个路径相一致。而`vsc`显然应该代表与版本控制系统有关的标识。还记得表0-2中的主命令列吗?这里的填入内容就应该该列中的某一项。在这里,由于talon项目使用的是Git,所以这里应该填入`git`。至于`repo-root`,它应该是与该处理程序关联的路径对应的Github网站的URL。在这里,这个路径是`hypermind.cn/talon`,那么这个URL就应该是`https://github.com/hyper-carrot/talon`。后者也是talon项目的实际网址。 +实际上,`content`属性中的`import-prefix`的位置上应该填入我们自定义的远程代码包导入路径的前缀。这个前缀应该与我们的处理程序关联的那个路径相一致。而`vcs`显然应该代表与版本控制系统有关的标识。还记得表0-2中的主命令列吗?这里的填入内容就应该该列中的某一项。在这里,由于talon项目使用的是Git,所以这里应该填入`git`。至于`repo-root`,它应该是与该处理程序关联的路径对应的Github网站的URL。在这里,这个路径是`hypermind.cn/talon`,那么这个URL就应该是`https://github.com/hyper-carrot/talon`。后者也是talon项目的实际网址。 好了,在我们做好上述处理程序之后,`go get hypermind.cn/talon/analyzer`命令的执行结果就会是正确的。`analyzer`代码包及其依赖包中的代码会被下载到GOPATH环境变量中的第一个工作区目录的src子目录中,然后被编译并安装。 From 1b4621792b4b370a315a4876ec8f040aff98ce0a Mon Sep 17 00:00:00 2001 From: Robert Hao Date: Sat, 22 Sep 2018 11:09:35 +0800 Subject: [PATCH 04/17] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 247cd85..569a083 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,15 @@ ## 相关源 -本教程在Github上的地址在[这里](https://github.com/g0hacker/go_command_tutorial)。如果你喜欢本教程,请不吝Star。如果你想贡献一份力量,欢迎提交Pull Request。 +本教程在Github上的地址在[这里](https://github.com/hyper0x/go_command_tutorial)。如果你喜欢本教程,请不吝Star。如果你想贡献一份力量,欢迎提交Pull Request。 -针对Go 1.3和1.4版本的教程已被放入分支[go1.3](https://github.com/g0hacker/go_command_tutorial/tree/go1.3)。而主分支此后一段时间内会致力于针对Go 1.5进行更新。 +针对Go 1.3和1.4版本的教程已被放入分支[go1.3](https://github.com/hyper0x/go_command_tutorial/tree/go1.3)。而主分支此后一段时间内会致力于针对Go 1.5进行更新。 -本教程中会提及一个名为```goc2p```的项目。该项目实际上是《Go并发编程实战》随书附带的示例项目。这本书中讲到的所有源码都在```goc2p```项目中。我已在《Go并发编程实战》出版之时将[```goc2p```](https://github.com/g0hacker/goc2p)项目放出。 +本教程中会提及一个名为```goc2p```的项目。该项目实际上是《Go并发编程实战》随书附带的示例项目。这本书中讲到的所有源码都在```goc2p```项目中。我已在《Go并发编程实战》出版之时将[```goc2p```](https://github.com/hyper0x/goc2p)项目放出。 ## 关于协议 -我希望这个项目中的内容永远是免费的。也就是说,任何组织和个人不应该出于商业目的而摘取其中的内容。更详细的条款请阅读本项目中的[LICENSE](https://github.com/g0hacker/go_command_tutorial/blob/master/LICENSE)文件。 +我希望这个项目中的内容永远是免费的。也就是说,任何组织和个人不应该出于商业目的而摘取其中的内容。更详细的条款请阅读本项目中的[LICENSE](https://github.com/hyper0x/go_command_tutorial/blob/master/LICENSE)文件。 ## 版本信息 书中内容及演示代码基于以下版本: From a7388a39081f106adc7ef3815454938580f60f25 Mon Sep 17 00:00:00 2001 From: Gavin Liu Date: Sat, 12 Oct 2019 15:03:57 +0800 Subject: [PATCH 05/17] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20docsify=20=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E5=8C=96=E6=96=87=E6=A1=A3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .nojekyll | 0 0.9.md | 9 +------ _sidebar.md | 30 +++++++++++++++++++++ index.html | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 .nojekyll create mode 100644 _sidebar.md create mode 100644 index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/0.9.md b/0.9.md index cfefd56..ddbf8c8 100644 --- a/0.9.md +++ b/0.9.md @@ -1,4 +1,4 @@ -### 0.9 go fmt与gofmt +# go fmt与gofmt `go fmt`命令会按照Go语言代码规范格式化指定代码包中的所有Go语言源码文件的代码,所有Go语言源码文件即包括命令源码文件、库源码文件和测试源码文件。注意,当代码包还有子代码包时,子代码包中的Go语言源码文件是不包含在内的。也就是说,`go fmt`命令只会格式化被直接保存在指定代码包对应目录下的Go语言源码文件。 @@ -95,10 +95,3 @@ if a == "print" { ``` 由上述示例可知,我们可以使用`gofmt`命令的交互模式格式化任意的代码片段。虽然会显示一行警告信息,但是格式化后的结果仍然会被打印出来。并且,在交互模式下,当我们输入的代码片段不符合Go语言的语法规则时,命令程序也会打印出错误提示信息。在其它方面,命令程序在交互模式与普通模式下的行为也是基本一致的。 - - - -## links - * [目录](catalog.md) - * 上一节: [go list](0.8.md) - * 下一节: [go fix与go tool fix](0.10.md) diff --git a/_sidebar.md b/_sidebar.md new file mode 100644 index 0000000..dd1cfde --- /dev/null +++ b/_sidebar.md @@ -0,0 +1,30 @@ +* [标志命令详解](0.0) + +* [go build](0.1) + +* [go install](0.2) + +* [go get](0.3) + +* [go clean](0.4) + +* [go doc 与 godoc](0.5) + +* [go run](0.6) + +* [go test](0.7) + +* [go list](0.8) + +* [go fmt 与 gofmt](0.9) + +* [go fix 与 go tool fix](0.10) + +* [go vet 与 go tool vet](0.11) + +* [go tool pprof](0.12) + +* [go tool cgo](0.13) + +* [go env](0.14) + diff --git a/index.html b/index.html new file mode 100644 index 0000000..75aa7ce --- /dev/null +++ b/index.html @@ -0,0 +1,76 @@ + + + + + Go 命令教程 + + + + + + + + + + +
+ + + + + + + + + + + + + + + + From c4949bb93c7e71311ec168b9ae5222905a7dd640 Mon Sep 17 00:00:00 2001 From: Alberto Date: Sat, 12 Oct 2019 18:04:04 +0800 Subject: [PATCH 06/17] Set theme jekyll-theme-merlot --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c50ff38 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-merlot \ No newline at end of file From 77b41878a02c6f072d2736d9e2791611125fd3d0 Mon Sep 17 00:00:00 2001 From: Roberto Date: Tue, 7 Jan 2020 23:34:48 +0800 Subject: [PATCH 07/17] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 569a083..ee6d86c 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ ## 作者介绍 -**郝林**,10年软件开发从业经验。搞过银行、电信软件和互联网社交等产品。对Go语言和Docker都情有独钟。现在正在从事互联网软件基础组件的构建以及Go语言的技术推广和社区运营等工作。他也是图灵原创技术图书《Go并发编程实战》和在线免费教程《Go语言第一课》的作者。 +**郝林**,从事互联网软件研发和管理工作已有15年,在银行、电信、社交网络、互联网金融、电子商务、大数据等领域都工作过。我对Go语言和Julia语言都情有独钟,并且目前正在独立从事编程教育研究、专业内容输出、在线社群运营等工作。我制作和发布不少很受欢迎的免费教程、技术图书和付费专栏,其中就包括本教程。另外还有(按时间排序):慕课网的免费教程[《Go语言第一课》](https://www.imooc.com/learn/345)、图灵原创技术图书[《Go并发编程实战》](https://www.ituring.com.cn/book/1950)、极客时间的[《Go语言核心36讲》](https://time.geekbang.org/column/intro/112)等。 ## 本教程的由来 -这份Go命令教程原先是我著的图书[《Go并发编程实战》](http://www.ituring.com.cn/book/1525)中的一部分。这部分内容与并发编程的关系不大,故被砍掉。但是它是有价值的,也算是我对Go语言官方提供的标准命令的一个学习笔记。所以,我觉得应该把它做成免费资源分享给大家。经出版社的认可,我将这份教程放在这里供广大Go语言爱好者阅读。 +这份Go命令教程原先是我撰写的图书[《Go并发编程实战》](http://www.ituring.com.cn/book/1525)中的一部分。这部分内容与并发编程的关系不大,故被砍掉。但是它是有价值的,也算是我对Go语言官方提供的标准命令的一个学习笔记。所以,我觉得应该把它做成免费资源分享给大家。经出版社的认可,我将这份教程放在这里供广大Go语言爱好者阅读。 -**信息更新:[《Go并发编程实战》第2版](http://www.ituring.com.cn/book/1950)会于2017年4月出版。我在考虑是否基于第2版和Go 1.8翻新本教程。** +**信息更新:[《Go并发编程实战》第2版](http://www.ituring.com.cn/book/1950)已于2017年4月出版。** ## 相关源 From 2fa476c6230d99d83b14ad155f9bab9e1276ae2d Mon Sep 17 00:00:00 2001 From: Roberto Date: Tue, 7 Jan 2020 23:38:43 +0800 Subject: [PATCH 08/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee6d86c..a36f996 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## 作者介绍 -**郝林**,从事互联网软件研发和管理工作已有15年,在银行、电信、社交网络、互联网金融、电子商务、大数据等领域都工作过。我对Go语言和Julia语言都情有独钟,并且目前正在独立从事编程教育研究、专业内容输出、在线社群运营等工作。我制作和发布不少很受欢迎的免费教程、技术图书和付费专栏,其中就包括本教程。另外还有(按时间排序):慕课网的免费教程[《Go语言第一课》](https://www.imooc.com/learn/345)、图灵原创技术图书[《Go并发编程实战》](https://www.ituring.com.cn/book/1950)、极客时间的[《Go语言核心36讲》](https://time.geekbang.org/column/intro/112)等。 +**郝林**,从事互联网软件研发和管理工作已有15年,在银行、电信、社交网络、互联网金融、电子商务、大数据等领域都工作过。我对Go语言和Julia语言都情有独钟,并且目前正在独立从事编程教育研究、专业内容输出、在线社群运营等工作。我制作和发布不少很受欢迎的免费教程、技术图书和付费专栏,其中就包括本教程。另外还有(按时间排序):慕课网的免费教程[《Go语言第一课》](https://www.imooc.com/learn/345)、人邮图灵的原创技术图书[《Go并发编程实战》](https://www.ituring.com.cn/book/1950)、极客时间的专栏[《Go语言核心36讲》](https://time.geekbang.org/column/intro/112)等。 ## 本教程的由来 From 4a12937a5db935fb3168c5b4f21e1632a9469baa Mon Sep 17 00:00:00 2001 From: Roberto Date: Wed, 8 Jan 2020 11:42:01 +0800 Subject: [PATCH 09/17] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a36f996..ff2375c 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,22 @@ ## 作者介绍 -**郝林**,从事互联网软件研发和管理工作已有15年,在银行、电信、社交网络、互联网金融、电子商务、大数据等领域都工作过。我对Go语言和Julia语言都情有独钟,并且目前正在独立从事编程教育研究、专业内容输出、在线社群运营等工作。我制作和发布不少很受欢迎的免费教程、技术图书和付费专栏,其中就包括本教程。另外还有(按时间排序):慕课网的免费教程[《Go语言第一课》](https://www.imooc.com/learn/345)、人邮图灵的原创技术图书[《Go并发编程实战》](https://www.ituring.com.cn/book/1950)、极客时间的专栏[《Go语言核心36讲》](https://time.geekbang.org/column/intro/112)等。 +**郝林**,从事互联网软件研发和管理工作已有15年,在银行、电信、社交网络、互联网金融、电子商务、大数据等领域都工作过。我对Go语言和Julia语言都情有独钟,并且目前正在独立从事编程教育研究、专业内容输出、在线社群运营等工作。我制作和发布过一些很受欢迎的免费教程、技术图书和付费专栏,其中就包括本教程。另外还有(按时间排序):慕课网的免费教程[《Go语言第一课》](https://www.imooc.com/learn/345)、人邮图灵的原创技术图书[《Go并发编程实战》](https://www.ituring.com.cn/book/1950)、极客时间的付费专栏[《Go语言核心36讲》](https://time.geekbang.org/column/intro/112)等。 ## 本教程的由来 这份Go命令教程原先是我撰写的图书[《Go并发编程实战》](http://www.ituring.com.cn/book/1525)中的一部分。这部分内容与并发编程的关系不大,故被砍掉。但是它是有价值的,也算是我对Go语言官方提供的标准命令的一个学习笔记。所以,我觉得应该把它做成免费资源分享给大家。经出版社的认可,我将这份教程放在这里供广大Go语言爱好者阅读。 -**信息更新:[《Go并发编程实战》第2版](http://www.ituring.com.cn/book/1950)已于2017年4月出版。** +**信息更新**: +- 2017-04-01:[《Go并发编程实战》第2版](http://www.ituring.com.cn/book/1950)已经出版了。 ## 相关源 -本教程在Github上的地址在[这里](https://github.com/hyper0x/go_command_tutorial)。如果你喜欢本教程,请不吝Star。如果你想贡献一份力量,欢迎提交Pull Request。 +本教程在Github上的地址在[这里](https://github.com/hyper0x/go_command_tutorial)。如果你喜欢本教程,请不吝Star。如果你想贡献一份力量,欢迎提交Pull Request(提示:请小步pr,避免大刀阔斧)。 针对Go 1.3和1.4版本的教程已被放入分支[go1.3](https://github.com/hyper0x/go_command_tutorial/tree/go1.3)。而主分支此后一段时间内会致力于针对Go 1.5进行更新。 -本教程中会提及一个名为```goc2p```的项目。该项目实际上是《Go并发编程实战》随书附带的示例项目。这本书中讲到的所有源码都在```goc2p```项目中。我已在《Go并发编程实战》出版之时将[```goc2p```](https://github.com/hyper0x/goc2p)项目放出。 +本教程中会提及一个名为`goc2p`的项目。该项目实际上是《Go并发编程实战》随书附带的示例项目。这本书中讲到的所有源码都在`goc2p`项目中。我已在《Go并发编程实战》出版之时将[`goc2p`](https://github.com/hyper0x/goc2p)项目放出。另外,《Go并发编程实战》第2版的示例项目在[这里](https://github.com/gopcp/example.v2),可供参考。 ## 关于协议 From 57c64ded715fd9fc71e7c764e36b15cceae68bcb Mon Sep 17 00:00:00 2001 From: Roberto Date: Thu, 23 Apr 2020 12:43:25 +0800 Subject: [PATCH 10/17] Update 0.12.md --- 0.12.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0.12.md b/0.12.md index c59e390..38fc8ce 100644 --- a/0.12.md +++ b/0.12.md @@ -520,7 +520,7 @@ _表0-23 pprof工具在交互模式下支持的命令_ gv -scale 0 (pprof) sh: 1: gv: not found -现在,输出信息有提示我们没有找到命令gv。gv是自由软件工程项目GNU(GNU's Not Unix)中的一款开源软件,用来以图形化的方式查看PDF文档。我们以同样的方式安装它。在Debian的Linux发行版及其衍生版下,执行命令```sudo apt-get install gv```,在Redhat的Linux发行版及其衍生版下,执行命令```yum install gv```。软件gv被安装好后,我们再次执行gv命令。在运行着图形界面软件的Linux操作系统下,会弹出这样一个窗口。如图5-3。 +现在,输出信息有提示我们没有找到命令gv。gv是自由软件工程项目GNU(GNU's Not Unix)中的一款开源软件,用来以图形化的方式查看PDF文档。我们以同样的方式安装它。在Debian的Linux发行版及其衍生版下,执行命令```sudo apt-get install gv```,在Redhat的Linux发行版及其衍生版下,执行命令```yum install gv```。软件gv被安装好后,我们再次执行gv命令。在运行着图形界面软件的Linux操作系统下,会弹出这样一个窗口。如图0-3。 ![pprof工具的gv命令的执行结果](images/0-3.jpg) @@ -789,4 +789,4 @@ _图0-4 使用kcachegrind工具查看概要数据_ 在本小节中,我们只使用```go tool pprof```命令对CPU概要文件进行了查看和分析。读者可以试着对内存概要文件和程序阻塞概要文件进行分析。 -相对于普通的编程方式来讲,并发编程都是复杂的。所以,我们就更需要像pprof这样的工具为我们保驾护航。大家可以将本小节当作一篇该工具的文档,并在需要时随时查看。 \ No newline at end of file +相对于普通的编程方式来讲,并发编程都是复杂的。所以,我们就更需要像pprof这样的工具为我们保驾护航。大家可以将本小节当作一篇该工具的文档,并在需要时随时查看。 From 5adb70d1545439125a1e5d4e1ee3de84d4d228cb Mon Sep 17 00:00:00 2001 From: gukz Date: Sun, 3 May 2020 21:10:17 +0800 Subject: [PATCH 11/17] fix lost of ` --- 0.12.md | 2 +- 0.13.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/0.12.md b/0.12.md index 38fc8ce..ab5d22f 100644 --- a/0.12.md +++ b/0.12.md @@ -26,7 +26,7 @@ } } -在函数```startCPUProfile```中,我们首先创建了一个用于存放CPU使用情况记录的文件。这个文件就是CPU概要文件,其绝对路径由```*cpuProfile```的值表示。然后,我们把这个文件的实例作为参数传入到函数```pprof.StartCPUProfile``中。如果此函数没有返回错误,就说明记录操作已经开始。需要注意的是,只有CPU概要文件的绝对路径有效时此函数才会开启记录操作。 +在函数```startCPUProfile```中,我们首先创建了一个用于存放CPU使用情况记录的文件。这个文件就是CPU概要文件,其绝对路径由```*cpuProfile```的值表示。然后,我们把这个文件的实例作为参数传入到函数```pprof.StartCPUProfile```中。如果此函数没有返回错误,就说明记录操作已经开始。需要注意的是,只有CPU概要文件的绝对路径有效时此函数才会开启记录操作。 如果我们想要在某一时刻停止CPU使用情况记录操作,就需要调用下面这个函数: diff --git a/0.13.md b/0.13.md index 6024bba..c3e1612 100644 --- a/0.13.md +++ b/0.13.md @@ -52,7 +52,7 @@ cgo也是一个Go语言自带的特殊工具。一般情况下,我们使用命 上面这段代码被保存在了Go语言库源码文件math.go中,并与源码文件rand.go在同一个代码包目录。在Go语言函数```Sqrt```中的```C.sqrt```是一个在C语言标准代码库math.h中的函数。它会返回参数的平方根。但是在第一行代码中,我们接收由函数C.sqrt返回的两个值。其中,第一个值即为C语言函数```sqrt```的结果。而第二个值就是我们上面所说的那个作为错误提示信息的变量。实际上,这个变量的类型是Go语言的```error```接口类型。它包装了一个C语言的全局变量errno。这个全局变量被定义在了C语言代码库errno.h中。cgo工具在为我们生成C语言源码文件时会默认引入两个C语言标准代码库,其中一个就是errno.h。所以我们并不用在Go语言源码文件中使用指令符#include显式的引入这个代码库。cgo工具默认为我们引入的另一个是C语言标准代码库string.h。它包含了很多用于字符串处理和内存处理的函数。 -在我们以“C.*”的形式调用C语言代码库时,有一点需要特别注意。在C语言中,如果一个函数的参数是一个具有固定尺寸的数组,那么实际上这个函数所需要的是指向这个数组的第一个元素的指针。C编译器能够正确识别和处理这个调用惯例。它可以自行获取到这个指针并传给函数。但是,这在我们使用cgo工具调用C语言代码库时是行不通的。在Go语言中,我们必须显式的将这个指向数组的第一个元素的指针传递给C语言的函数,像这样:``C.func1(&x[0])````。 +在我们以“C.*”的形式调用C语言代码库时,有一点需要特别注意。在C语言中,如果一个函数的参数是一个具有固定尺寸的数组,那么实际上这个函数所需要的是指向这个数组的第一个元素的指针。C编译器能够正确识别和处理这个调用惯例。它可以自行获取到这个指针并传给函数。但是,这在我们使用cgo工具调用C语言代码库时是行不通的。在Go语言中,我们必须显式的将这个指向数组的第一个元素的指针传递给C语言的函数,像这样:```C.func1(&x[0])```。 另一个需要特别注意的地方是,在C语言中没有像Go语言中独立的字符串类型。C语言使用最后一个元素为‘\0’的字符数组来代表字符串。在Go语言的字符串和C语言的字符串之间进行转换的时候,我们就需要用到代码包```C```中的```C.C.CString```、```C.GoString```和```C.GoStringN```等函数。这些转换操作是通过对字符串数据的拷贝来完成的。Go语言内存管理器并不能感知此类内存分配操作。因为它们是由C语言代码引发的。所以,我们在使用与```C.CString```函数类似的会导致内存分配操作的函数之后,需要调用代码包C的free函数以手动的释放内存。这里有一个小技巧,即我们可以把对```C.free```函数的调用放到```defer```语句中或者放入在defer之后的匿名函数中。这样就可以保证在退出当前函数之前释放这些被分配的内存了。请看下面这个示例: @@ -68,7 +68,7 @@ cgo也是一个Go语言自带的特殊工具。一般情况下,我们使用命 在前面我们已经提到过,在导入代码包C的语句之上可以加入若干个为cgo工具而写的若干注释行(也被叫做序文)。并且,以#include和一个空格开始的注释行可以用来引入一个C语言的接口文件。我们也把序文中这种形式的字符串叫做指令符。指令符```#cgo```的用途是为编译器和连接器提供标记。这些标记在编译当前源码文件中涉及到代码包```C```的那部分代码时会被用到。 -标记```CFLAGS```和```LDFLAGS``可以被放在指令符```#cgo```之后,并用于定制编译器gcc的行为。gcc(GNU Compiler Collection,GNU编译器套装),是一套由GNU开发的开源的编程语言编译器。它是GNU项目的关键部分,也是类Unix操作系统(也包括Linux操作系统)中的标准编译器。gcc(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。gcc原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。不过,gcc变得可以处理更多的语言。现在,gcc中包含了很多针对特定编程语言的编译器。我们在本节第一小节的末尾提及的gccgo就是这款套件中针对Go语言的编译器。标记CFLAGS可以指定用于gcc中的C编译器的选项。它尝尝用于指定头文件(.h文件)的路径。而标记LDFLAGS则可以指定gcc编译器会用到的一些优化参数,也可以用来告诉链接器需要用到的C语言代码库文件的位置。 +标记```CFLAGS```和```LDFLAGS```可以被放在指令符```#cgo```之后,并用于定制编译器gcc的行为。gcc(GNU Compiler Collection,GNU编译器套装),是一套由GNU开发的开源的编程语言编译器。它是GNU项目的关键部分,也是类Unix操作系统(也包括Linux操作系统)中的标准编译器。gcc(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。gcc原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。不过,gcc变得可以处理更多的语言。现在,gcc中包含了很多针对特定编程语言的编译器。我们在本节第一小节的末尾提及的gccgo就是这款套件中针对Go语言的编译器。标记CFLAGS可以指定用于gcc中的C编译器的选项。它尝尝用于指定头文件(.h文件)的路径。而标记LDFLAGS则可以指定gcc编译器会用到的一些优化参数,也可以用来告诉链接器需要用到的C语言代码库文件的位置。 为了清晰起见,我们可以把这些标记及其值拆分成多个注释行,并均以指令符```#cgo```作为前缀。另外,在指令符```#cgo```和标记之间,我们也可以加入一些可选的内容,即环境变量GOOS和GOARCH中的有效值。这样,我们就可以使这些标记只在某些操作系统和/或某些计算架构的环境下起作用了。示例如下: @@ -500,8 +500,8 @@ Go语言可以使它的函数被C语言代码所用。这是通过使用一个 hc@ubt:~/golang/goc2p/basic/cgo/lib$ go build # basic/cgo/lib - /tmp/go-build477634277/basic/cgo/lib/_obj/go_export.cgo2.o: In function `_cgo_cc103c85817e_Cfunc_CFunction1': - ./go_export.go:34: undefined reference to `CFunction1' + /tmp/go-build477634277/basic/cgo/lib/_obj/go_export.cgo2.o: In function '_cgo_cc103c85817e_Cfunc_CFunction1': + ./go_export.go:34: undefined reference to 'CFunction1' collect2: ld return 1 构建并没有成功完成。根据错误提示信息我们获知,C语言函数```CFunction1```未被定义。这个问题的原因是我们并没有在Go语言源码文件go_export.go的序文中写入C语言函数```CFunction1```的实现,也即未对它进行定义。我们之前说过,在这种情况下,对应函数的定义应该被放到其它Go语言源码文件的序文或者C语言源码文件中。现在,我们在当前目录下创建一个新的Go语言源码文件go_export_def.go。其内容如下: @@ -528,7 +528,7 @@ Go语言可以使它的函数被C语言代码所用。这是通过使用一个 显然,这次的构建成功完成。当然单独构建代码包```basic/cgo/lib```并不是必须的。我们在这里是为了检查该代码包中的代码(包括Go语言代码和C语言代码)是否都能够被正确编译。 -还记得goc2p项目的代码包basic/cgo中的命令源码文件cgo_demo.go。现在我们在它的main函数的最后加入一行新代码:```cgo.CallCFunc()```,即调用在代码包``basic/cgo/lib```中的库源码文件go_export.go的函数。然后,我们运行这个命令源码文件: +还记得goc2p项目的代码包basic/cgo中的命令源码文件cgo_demo.go。现在我们在它的main函数的最后加入一行新代码:```cgo.CallCFunc()```,即调用在代码包```basic/cgo/lib```中的库源码文件go_export.go的函数。然后,我们运行这个命令源码文件: hc@ubt:~/golang/goc2p/basic/cgo$ go run cgo_demo.go The square root of 2.330000 is 1.526434. @@ -555,4 +555,4 @@ Go语言可以使它的函数被C语言代码所用。这是通过使用一个 CFunction1() is called. GoFunction1() is called. -在上例中,我们首先删除了代码包```basic/cgo/lib```目录下的子目录_obj,以此来保证原始的测试环境。然后,我们直接运行了命令源码文件cgo_demo.go。在这个源码文件中,包含了对代码包```basic/cgo/lib```中函数的调用语句,而在这些函数中又包含了对代码包C的引用。从输出信息我们可以看出,命令源码文件cgo_demo.go的运行成功的完成了。这也验证了标准go命令在这方面的功能。不过,有时候我们还是很有必要单独使用```go tool cgo```命令,比如对相关的Go语言代码和C语言代码的功能进行验证或者需要通过标记定制化运行cgo工具的时候。另外,如果我们通过标准go命令构建或者安装直接或间接导入了代码C的命令源码文件,那么在生成的可执行文件中就会包含动态导入数据和动态链接器信息。我们可以使用```go tool cgo```命令查看可执行文件中的这些信息。 \ No newline at end of file +在上例中,我们首先删除了代码包```basic/cgo/lib```目录下的子目录_obj,以此来保证原始的测试环境。然后,我们直接运行了命令源码文件cgo_demo.go。在这个源码文件中,包含了对代码包```basic/cgo/lib```中函数的调用语句,而在这些函数中又包含了对代码包C的引用。从输出信息我们可以看出,命令源码文件cgo_demo.go的运行成功的完成了。这也验证了标准go命令在这方面的功能。不过,有时候我们还是很有必要单独使用```go tool cgo```命令,比如对相关的Go语言代码和C语言代码的功能进行验证或者需要通过标记定制化运行cgo工具的时候。另外,如果我们通过标准go命令构建或者安装直接或间接导入了代码C的命令源码文件,那么在生成的可执行文件中就会包含动态导入数据和动态链接器信息。我们可以使用```go tool cgo```命令查看可执行文件中的这些信息。 From acecec833414d9e0fca0d596951b4854afcdc64b Mon Sep 17 00:00:00 2001 From: voiddme Date: Tue, 29 Sep 2020 19:39:16 +0800 Subject: [PATCH 12/17] =?UTF-8?q?style:=20style-fix=201.=20`****`=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A9=BA=E6=A0=BC,=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=97=A0=E6=B3=95=20parse=20=E9=97=AE=E9=A2=98=202.=20``?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A,?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=97=A0=E6=B3=95=E5=B1=95=E7=A4=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0.0.md b/0.0.md index 7c50936..1ee2a59 100644 --- a/0.0.md +++ b/0.0.md @@ -2,7 +2,7 @@ Go语言的1.5版本在标准命令方面有了重大变更。这倒不是说它们的用法有多大的变化,而是说它们的底层支持已经大变样了。让我们先来对比一下`$GOROOT/pkg/tool/<平台相关目录>`中的内容。以下简称此目录为Go工具目录。 -**插播:**平台相关目录即以_命名的目录,用于存放因特定平台的不同而不同的代码包归档文件或可执行文件。其中,代表特定平台的操作系统代号,而则代表特定平台的计算架构代号。使用`go env`命令便可查看它们在你的计算机中的实际值。 +**插播:** 平台相关目录即以 `_` 命名的目录,用于存放因特定平台的不同而不同的代码包归档文件或可执行文件。其中,`` 代表特定平台的操作系统代号,而 `` 则代表特定平台的计算架构代号。使用 `go env` 命令便可查看它们在你的计算机中的实际值。 1.4版本的Go工具目录的内容如下: @@ -19,7 +19,7 @@ addr2line asm compile dist fix nm pack tour api cgo cover doc link objdump pprof trace yacc ``` -可以看到,1.5版本的目录内容精简了不少。这是因为Go 1.5的编译器、链接器都已经完全用Go语言重写了。而在这之前,它们都是用C语言写的,因此不得不为每类平台编写不同的程序并生成不同的文件。例如,8g、6g和5g分别是gc编译器在x86(32bit)、x86-64(64bit)和ARM计算架构的计算机上的实现程序。相比之下,用Go语言实现的好处就是,编译器和链接器都将是跨平台的了。简要来说,Go 1.5版本的目录中的文件compile即是统一后的编译器,而文件link则是统一后的链接器。 +可以看到,1.5版本的目录内容精简了不少。这是因为Go 1.5的编译器、链接器都已经完全用Go语言重写了。而在这之前,它们都是用C语言写的,因此不得不为每类平台编写不同的程序并生成不同的文件。例如,8g、6g和5g分别是gc编译器在x86(32bit)、x86-64(64bit)和ARM计算架构的计算机上的实现程序。相比之下,用Go语言实现的好处就是,编译器和链接器都将是跨平台的了。简要来说,Go 1.5版本的目录中的文件 compile 即是统一后的编译器,而文件 link 则是统一后的链接器。 本教程并不会讲解Go语言的编译器、链接器以及其它工具是怎样被编写出来的,并只会关注于怎样用好包含它们在内的Go语言自带的命令和工具。 From ee99c46ea0b8beed9dca1402993c93552530960e Mon Sep 17 00:00:00 2001 From: haolin Date: Wed, 23 Dec 2020 11:24:36 +0800 Subject: [PATCH 13/17] Fix a typo --- _sidebar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_sidebar.md b/_sidebar.md index dd1cfde..172a9e4 100644 --- a/_sidebar.md +++ b/_sidebar.md @@ -1,4 +1,4 @@ -* [标志命令详解](0.0) +* [标准命令详解](0.0) * [go build](0.1) From cea100292d8bc21b0a1121d6247fc7970b9766d8 Mon Sep 17 00:00:00 2001 From: YuLe Date: Sun, 11 Apr 2021 20:39:54 +0800 Subject: [PATCH 14/17] Update 0.1.md --- 0.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0.1.md b/0.1.md index febfb83..39b5f10 100644 --- a/0.1.md +++ b/0.1.md @@ -56,7 +56,7 @@ hc@ubt:~/golang/goc2p/src/basic/pkginit$ ls initpkg_demo initpkg_demo.go ``` -我们在执行命令`go build -v initpkg_demo.go`之后被打印出的`command-line-arguments`”`就是命令程序为命令源码文件initpkg_demo.go生成的虚拟代码包的包名。顺带说一句, +我们在执行命令`go build -v initpkg_demo.go`之后被打印出的`command-line-arguments`就是命令程序为命令源码文件initpkg_demo.go生成的虚拟代码包的包名。顺带说一句, 命令`go build`会把编译命令源码文件后生成的结果文件存放到执行该命令时所在的目录下。这个所说的结果文件就是与命令源码文件对应的可执行文件。它的名称会与命令源码文件的主文件名相同。 From e964f64e5f13d5bcde77e12a08134b630d14605f Mon Sep 17 00:00:00 2001 From: YuLe Date: Sun, 11 Apr 2021 21:06:46 +0800 Subject: [PATCH 15/17] Update 0.2.md --- 0.2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0.2.md b/0.2.md index b4ac58e..fe19f11 100644 --- a/0.2.md +++ b/0.2.md @@ -66,7 +66,7 @@ $HOME/golang/goc2p: pkg/ linux_386/ pkgtool.a - src/ + src/ ``` 现在pkg目录中多了一个子目录。读过0.0节的读者应该已经知道,linux_386被叫做平台相关目录。它的名字可以由`${GOOS}_${GOARCH}`来得到。其中,`${GOOS}`和`${GOARCH}`分别是当前操作系统中的环境变量GOOS和GOARCH的值。如果它们不存在,那么Go语言就会使用其内部的预定值。上述示例在计算架构为386且操作系统为Linux的计算机上运行。所以,这里的平台相关目录即为linux_386。我们还看到,在goc2p项目中的平台相关目录下存在一个文件,名称是pkgtool.a。这就是代码包`pkgtool`的归档文件,文件名称是由代码包名称与“.a”后缀组合而来的。 @@ -173,4 +173,4 @@ go install: no install location for .go files listed on command line (GOBIN not 而且,在我们为环境变量GOBIN设置了正确的值之后,这个错误提示信息仍然会出现。这是因为,只有在安装命令源码文件的时候,命令程序才会将环境变量GOBIN的值作为结果文件的存放目录。而在安装库源码文件时,在命令程序内部的代表结果文件存放目录路径的那个变量不会被赋值。最后,命令程序会发现它依然是个无效的空值。所以,命令程序会同样返回一个关于“无安装位置”的错误。这就引出一个结论,我们只能使用安装代码包的方式来安装库源码文件,而不能在`go install`命令罗列并安装它们。另外,`go install`命令目前无法接受标记`-o`以自定义结果文件的存放位置。这也从侧面说明了`go install`命令不支持针对库源码文件的安装操作。 -至此,我们对怎样用`go install`命令来安装代码包以及命令源码文件进行了说明。如果你已经熟知了`go build`命令,那么理解这些内容应该不在话下。 \ No newline at end of file +至此,我们对怎样用`go install`命令来安装代码包以及命令源码文件进行了说明。如果你已经熟知了`go build`命令,那么理解这些内容应该不在话下。 From 096d3c2461fa9af3e244c244d25726cc6d3ce7cf Mon Sep 17 00:00:00 2001 From: jincheng9 Date: Sat, 12 Mar 2022 13:56:07 +0800 Subject: [PATCH 16/17] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff2375c..2578466 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,4 @@ | 系统 | 版本信息 |---------|------ -|Golang |1.3(will be abandoned) + 1.5(in prograss) +|Golang |1.3(will be abandoned) + 1.5(in progress) From 9a76c0675236f04b9584d98ee9b9a6001eb771cb Mon Sep 17 00:00:00 2001 From: Renato Date: Fri, 25 Nov 2022 18:52:51 +0800 Subject: [PATCH 17/17] Fix a --- 0.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0.1.md b/0.1.md index 39b5f10..78dd48d 100644 --- a/0.1.md +++ b/0.1.md @@ -172,7 +172,7 @@ logging + `-compiler` -此标记用于指定当前使用的编译器的名称。其值可以为`gc`或`gccgo`。其中,gc编译器即为Go语言自带的编辑器,而gccgo编译器则为GCC提供的Go语言编译器。而GCC则是GNU项目出品的编译器套件。GNU是一个众所周知的自由软件项目。在开源软件界不应该有人不知道它。好吧,如果你确实不知道它,赶紧去google吧。 +此标记用于指定当前使用的编译器的名称。其值可以为`gc`或`gccgo`。其中,gc编译器即为Go语言自带的编译器,而gccgo编译器则为GCC提供的Go语言编译器。而GCC则是GNU项目出品的编译器套件。GNU是一个众所周知的自由软件项目。在开源软件界不应该有人不知道它。好吧,如果你确实不知道它,赶紧去google吧。 + `-gccgoflags`