初识Go语言
Go语言是一门新生语言,从其出现就备受大家的喜爱。
本章首先简要介绍Go语言的发展历史,并较详细地分析了“Hello World”程序在各个祖先语言中演化过程。然后,对以数组、字符串和切片为代表的基础结构,对以函数、方法和接口所体现的面向过程和鸭子对象的编程,以及Go语言特有的并发编程模型和错误处理哲学做了简单介绍。最后,针对macOS、Windows、Linux几个主流的开发平台,推荐了几个较友好的Go语言编辑器和集成开发环境,因为好的工具可以极大地提高我们的效率。
Go语言创世纪
Go语言最初由Google公司的Robert Griesemer、Ken Thompson和Rob Pike三个大牛于2007年开始设计发明,设计新语言的最初的洪荒之力来自于对超级复杂的C++11特性的吹捧报告的鄙视,最终的目标是设计网络和多核时代的C语言。到2008年中期,语言的大部分特性设计已经完成,并开始着手实现编译器和运行时,大约在这一年Russ Cox作为主力开发者加入。到了2010年,Go语言已经逐步趋于稳定,并在9月正式发布Go语言并开源了代码。
Go语言很多时候被描述为“类C语言”,或者是“21世纪的C语言”。从各种角度看,Go语言确实是从C语言继承了相似的表达式语法、控制流结构、基础数据类型、调用参数传值、指针等诸多编程思想,还有彻底继承和发扬了C语言简单直接的暴力编程哲学等。
《Go语言圣经》中给出的Go语言的基因图谱,我们可以从中看到有哪些编程语言对Go语言产生了影响。
首先看基因图谱的左边一支。可以明确看出Go语言的并发特性是由贝尔实验室的Hoare于1978年发布的CSP理论演化而来。其后,CSP并发模型在Squeak/NewSqueak和Alef等编程语言中逐步完善并走向实际应用,最终这些设计经验被消化并吸收到了Go语言中。业界比较熟悉的Erlang编程语言的并发编程模型也是CSP理论的另一种实现。
再看基因图谱的中间一支。中间一支主要包含了Go语言中面向对象和包特性的演化历程。Go语言中包和接口以及面向对象等特性则继承自Niklaus Wirth所设计的Pascal语言以及其后所的衍生的相关编程语言。其中包的概念、包的导入和声明等语法主要来自于Modula-2编程语言,面向对象特性所提供的方法的声明语法等则来自于Oberon编程语言。最终Go语言演化出了自己特有的支持鸭子面向对象模型的隐式接口等诸多特性。
最后是基因图谱的右边一支,这是对C语言的致敬。Go语言是对C语言最彻底的一次扬弃,不仅仅是语法和C语言有着很多差异,最重要的是舍弃了C语言中灵活但是危险的指针运算。而且,Go语言还重新设计了C语言中部分不太合理运算符的优先级,并在很多细微的地方都做了必要的打磨和改变。当然,C语言中少即是多、简单直接的暴力编程哲学则被Go语言更彻底地发扬光大了(Go语言居然只有25个关键字,sepc语言规范还不到50页))。
Go语言其它的一些特性零散地来自于其他一些编程语言;比如iota语法是从APL语言借鉴,词法作用域与嵌套函数等特性来自于Scheme语言(和其他很多编程语言)。Go语言中也有很多自己发明创新的设计。比如Go语言的切片为轻量级动态数组提供了有效的随机存取的性能,这可能会让人联想到链表的底层的共享机制。还有Go语言新发明的defer语句(Ken发明)也是神来之笔。
来自贝尔实验室特有基因
作为Go语言标志性的并发编程特性则来自于贝尔实验室的Tony Hoare于1978年发表鲜为外界所知的关于并发研究的基础文献:顺序通信进程( communicating sequential processes ,缩写为CSP)。在最初的CSP论文中,程序只是一组没有中间共享状态的平行运行的处理过程,它们之间使用管道进行通信和控制同步。Tony Hoare的CSP并发模型只是一个用于描述并发性基本概念的描述语言,它并不是一个可以编写可执行程序的通用编程语言。
CSP并发模型最经典的实际应用是来自爱立信发明的Erlang编程语言。不过在Erlang将CSP理论作为并发编程模型的同时,同样来自贝尔实验室的Rob Pike以及其同事也在不断尝试将CSP并发模型引入当时的新发明的编程语言中。他们第一次尝试引入CSP并发特性的编程语言叫Squeak(老鼠的叫声),是一个用于提供鼠标和键盘事件处理的编程语言,在这个语言中管道是静态创建的。然后是改进版的Newsqueak语言(新版老鼠的叫声),新提供了类似C语言语句和表达式的语法,还有类似Pascal语言的推导语法。 Newsqueak是一个带垃圾回收的纯函数式语言,它再次针对键盘、鼠标和窗口事件管理。但是在Newsqueak语言中管道已经是动态创建的,管道属于第一类值、可以保存到变量中。然后是Alef编程语言(Alef也是C语言之父Ritchie比较喜爱的编程语言),Alef语言试图将Newsqueak语言改造为系统编程语言,但是因为缺少垃圾回收机制而导致并发编程很痛苦(这也是继承C语言手工管理内存的代价)。在Aelf语言之后还有一个叫Limbo的编程语言(地狱的意思),这是一个运行在虚拟机中的脚本语言。 Limbo语言是Go语言最接近的祖先,它和Go语言有着最接近的语法。到设计Go语言时,Rob Pike在CSP并发编程模型的实践道路上已经积累了几十年的经验,关于Go语言并发编程的特性完全是信手拈来,新编程语言的到来也是水到渠成了。
从早期提交日志中也可以看出,Go语言是从Ken Thompson发明的B语言、Dennis M. Ritchie发明的C语言逐步演化过来的,它首先是C语言家族的成员,因此很多人将Go语言称为21世纪的C语言。
纵观整个贝尔实验室的编程语言的发展进程,从B语言、C语言、Newsqueak、Alef、Limbo语言一路走来,Go语言继承了来着贝尔实验室的半个世纪的软件设计基因,终于完成了C语言革新的使命。纵观这几年来的发展趋势,Go语言已经成为云计算、云存储时代最重要的基础编程语言。
Hello, World!
按照惯例,介绍所有编程语言的第一个程序都是“Hello, World!”。虽然本教假设读者已经了解了Go语言,但是我们还是不想打破这个惯例(因为这个传统正是从Go语言的前辈C语言传承而来的)。 代码展示的Go语言程序输出的是“Hello, World!”。
package main
import "fmt"
func main() {
fmt.Println( "Hello, World!" )
}
将以上代码保存到 hello.go 文件中。然后进入命令行并切换到 hello.go 文件所在的目录。目前我们可以将Go语言当作脚本语言,在命令行中直接输入 go run hello.go 来运行程序。如果一切正常的话。应该可以在命令行看到输出”Hello, World!”的结果。
现在,让我们简单介绍一下程序。所有的Go程序,都是由最基本的函数和变量构成,函数和变量被组织到一个个单独的Go源文件中,这些源文件再按照作者的意图组织成合适的package,最终这些package再有机地组成一个完整的Go语言程序。其中,函数用于包含一系列的语句(指明要执行的操作序列),以及执行操作时存放数据的变量。 我们这个程序中函数的名字是main。虽然Go语言中,函数的名字没有太多的限制,但是main包中的main函数默认是每一个可执行程序的入口。而package则用于包装和组织相关的函数、变量和常量。在使用一个package之前,我们需要使用import语句导入包。 例如,我们这个程序中导入了fmt包(fmt是format单词的缩写,表示格式化相关的包),然后我们才可以使用fmt包中的Println函数。
而双引号包含的“Hello, World!”则是Go语言的字符串面值常量。和C语言中的字符串不同,Go语言中的字符串内容是不可变更的。在以字符串作为参数传递给fmt.Println函数时,字符串的内容并没有被复制——传递的仅仅是字符串的地址和长度(字符串的结构在 reflect.StringHeader 中定义)。 在Go语言中,函数参数都是以复制的方式(不支持以引用的方式)传递(比较特殊的是,Go语言闭包函数对外部变量是以引用的方式使用)。
Go语言特性
Go语言是Google公司开发的一种静态型、编译型并自带垃圾回收和并发的编程语言。
Go语言的风格类似于C语言。其语法在C语言的基础上进行了大幅的简化,去掉了不需要的表达式括号,循环也只有for一种表示方法,就可以实现数值、键值等各种遍历。因此,Go语言上手非常容易。
Go语言最有特色的特性莫过于goroutine。Go语言在语言层可以通过goroutine对函数实现并发执行。goroutine类似于线程但是并非线程,goroutine会在Go语言运行时进行自动调度。因此,Go语言非常适合用于高并发网络服务的编写。
上手容易
很多读者表示自己是在看了介绍后才开始了解这门语言的。他们一般也会使用两到三门编程语言。Go语言对于他们来说,也就是一到两天的熟悉过程,之后就可以开始使用Go语言解决具体问题了。大约一周左右已经可以使用Go语言完成既定的任务了。
Go语言这种从零开始使用到解决问题的速度,在其他语言中是完全不可想象的。学过C++的朋友都知道,一到两年大强度的理论学习和实战操练也只能学到这门语言的皮毛,以及知道一些基本的避免错误的方法。
那么,Go语言到底有多么简单?下面从实现一个HTTP服务器开始了解。
HTTP文件服务器是常见的Web服务之一。开发阶段为了测试,需要自行安装Apache或Nginx服务器,下载安装配置需要大量的时间。使用Go语言实现一个简单的HTTP服务器只需要几行代码
package main
import ( "net/http")
func main() {
http.Handle("/", http.FileServer(http.Dir(".")))
http.ListenAndServe(":8080", nil)
}
- 标记当前文件为main包,main包也是Go程序的入口包。
- 导入net/http包,这个包的作用是HTTP的基础封装和访问。
- 程序执行的入口函数main()。
- 使用http.FileServer文件服务器将当前目录作为根目录(“/”)的处理器,访问根目录,就会进入当前目录。
- 默认的HTTP服务侦听在本机8080端口。
把这个源码保存为main.go,安装Go语言的开发包,在命令行输入如下命令行:
$ go run httpserver.go
在浏览器里输入http://127.0.0.1:8080即可浏览文件,这些文件正是当前目录在HTTP服务器上的映射目录。
编译输出可执行文件
Go语言的代码可以直接输出为目标平台的原生可执行文件。Go语言不使用虚拟机,只有运行时(runtime)提供垃圾回收和goroutine调度等。
Go语言使用自己的链接器,不依赖任何系统提供的编译器、链接器。因此编译出的可执行文件可以直接运行在几乎所有的操作系统和环境中。
从Go 1.5版本之后,Go语言实现自举,实现了使用Go语言编写Go语言编译器及所有工具链的功能。 使用最经典的Go语言版的“hello world”源码来编译输出一个可执行文件
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
将这段代码保存为main.go,确认安装Go语言的开发包,使用如下指令可以将这段代码编译为可执行文件:
$ go build ./helloworld.go
执行hello world的可执行文件就可以输出“hello world”。
Go语言不仅可以输出可执行文件,还可以编译输出能导入C语言的静态库、动态库。
同时从Go 1.7版本开始,Go语言支持将代码编译为插件。使用插件可以动态加载需要的模块,而不是一次性将所有的代码编译为一个可执行文件。
工程结构简单
Go语言的源码无须头文件,编译的文件都来自于后缀名为go的源码文件;Go语言无须解决方案、工程文件和Make File。 只要将工程文件按照GOPATH的规则进行填充,即可使用go build/go install进行编译,编译安装的二进制可执行文件统一放在bin文件夹下。
编译速度快
Go语言可以利用自己的特性实现并发编译,并发编译的最小元素是包。从Go 1.9版本开始,最小并发编译元素缩小到函数,整体编译速度提高了20%。
另外,Go语言语法简单,具有严谨的工程结构设计、没有头文件、不允许包的交叉依赖等规则,在很大程度上加速了编译的过程。
高性能
Go语言在性能上更接近于Java语言,虽然在某些测试用例上不如经过多年优化的Java语言,但毕竟Java语言已经经历了多年的积累和优化。Go语言在未来的版本中会通过不断的版本优化提高单核运行性能。
原生支持并发
Go语言的特性就是从语言层原生支持并发,无须第三方库、开发者的编程技巧及开发经验就可以轻松地在Go语言运行时来帮助开发者决定怎么使用CPU资源。
Go语言的并发是基于goroutine,goroutine类似于线程,但并非线程。可以将goroutine理解为一种虚拟线程。Go语言运行时会参与调度goroutine,并将goroutine合理地分配到每个CPU中,最大限度地使用CPU性能。
多个goroutine中,Go语言使用通道(channel)进行通信,程序可以将需要并发的程序设计为生产者和消费者的模式,将数据放入通道。通道的另外一端的代码将这些数据进行并发计算并返回结果。
下面代码中的生产者每秒生成一个字符串,并通过通道传给消费者,生产者使用两个goroutine并发运行,消费者在main()函数的goroutine中进行处理。
01 package main
02
03 import (
04 "fmt"
05 "math/rand"
06 "time"
07 )
08
09 // 数据生产者
10 func producer(header string, channel chan<- string) {
11
12 // 无限循环,不停地生产数据
13 for {
14 // 将随机数和字符串格式化为字符串发送给通道
15 channel <- fmt.Sprintf("%s: %v", header, rand.Int31())
16
17 // 等待1秒
18 time.Sleep(time.Second)
19 }
20 }
21
22 // 数据消费者
23 func customer(channel <-chan string) {
24
25 // 不停地获取数据
26 for {
27 // 从通道中取出数据,此处会阻塞直到信道中返回数据
28 message := <-channel
29
30 // 打印数据
31 fmt.Println(message)
32 }
33 }
34
35 func main() {
36 // 创建一个字符串类型的通道
37 channel := make(chan string)
38 // 创建producer()函数的并发goroutine
39 go producer("cat", channel)
40 go producer("dog", channel)
41 // 数据消费函数
42 customer(channel)
43 }
代码说明如下:
- 第3行,导入格式化(fmt)、随机数(math/rand)、时间(time)包参与编译。
- 第10行,生产数据的函数,传入一个标记类型的字符串及一个只能写入的通道。
- 第13行,for{}构成一个无限循环。
- 第15行,使用rand.Int31()生成一个随机数,使用fmt.Sprintf()函数将header和随机数格式化为字符串。
- 第18行,使用time.Sleep()函数暂停1秒再执行这个函数。如果在goroutine中执行时,暂停不会影响其他goroutine的执行。
- 第23行,消费数据的函数,传入一个只能写入的通道。
- 第26行,构造一个不断消费消息的循环。
- 第28行,从通道中取出数据。
- 第31行,将取出的数据进行打印。
- 第35行,程序的入口函数,总是在程序开始时执行。
- 第37行,实例化一个字符串类型的通道。
- 第39行和第40行,并发执行一个生产者函数,两行分别创建了这个函数搭配不同参数的两个goroutine。
- 第42行,执行消费者函数通过通道进行数据消费。 整段代码中,没有线程创建,没有线程池也没有加锁,仅仅通过关键字go实现goroutine,和通道实现数据交换。
性能分析
安装Go语言开发包后,使用Go语言工具链可以直接进行Go代码的性能分析。Go的性能分析工具将性能数据以二进制文件输出,配合Graphviz即可将性能分析数据以图形化的方式展现出来。
强大的标准库
Go语言的标准库覆盖网络、系统、加密、编码、图形等各个方面,可以直接使用标准库的http包进行HTTP协议的收发处理;网络库基于高性能的操作系统通信模型(Linux的epoll、Windows的IOCP);所有的加密、编码都内建支持,不需要再从第三方开发者处获取。Go语言的编译器也是标准库的一部分,通过词法器扫描源码,使用语法树获得源码逻辑分支等。Go语言的周边工具也是建立在这些标准库上。在标准库上可以完成几乎大部分的需求。
代码风格清晰、简单
Go语言写起来类似于C语言,因此熟悉C语言及其派生语言(C++、C#、Objective-C等)的人都会迅速熟悉这门语言。
C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的基础上取其精华,弃其糟粕,将C语言中较为容易发生错误的写法进行调整,做出相应的编译提示。
- 去掉循环冗余括号
Go语言在众多大师的丰富实战经验的基础上诞生,去除了C语言语法中一些冗余、烦琐的部分。
下面的代码是C语言的数值循环:
// C语言的for数值循环 for(int a = 0;a<10;a++){ // 循环代码 }
在Go语言中,这样的循环变为:
for a := 0;a<10;a++{ // 循环代码 }
for两边的括号被去掉,int声明被简化为“:=”,直接通过编译器右值推导获得a的变量类型并声明。
- 强制的代码风格 Go语言中,左括号必须紧接着语句不换行。其他样式的括号将被视为代码编译错误。这个特性刚开始会使开发者有一些不习惯,但随着对Go语言的不断熟悉,开发者就会发现风格统一让大家在阅读代码时把注意力集中到了解决问题上,而不是代码风格上。
同时Go语言也提供了一套格式化工具。一些Go语言的开发环境或者编辑器在保存时,都会使用格式化工具进行修改代码的格式化,让代码提交时已经是统一格式的代码。
- 不再纠结于i++和++i
C语言非常经典的考试题为:
int a, b; a = i++; b = ++i;
这种题目对于初学者简直摸不着头脑。为什么一个简单的自增表达式需要有两种写法?
在Go语言中,自增操作符不再是一个操作符,而是一个语句。因此,在Go语言中自增只有一种写法:
i++
如果写成前置自增“++i”,或者赋值后自增“a=i++”都将导致编译错误。
使用Go语言的项目
Go语言从发布1.0版本以来备受众多开发者关注并得到广泛使用。Go语言的简单、高效、并发特性吸引了众多传统语言开发者的加入,而且人数越来越多。
使用Go语言开发的开源项目非常多。早期的Go语言开源项目只是通过Go语言与传统项目进行C语言库绑定实现,如Qt、Sqlite等。后期的很多项目都使用Go语言进行重新原生实现,这个过程相对于其他语言要简单一些,这也促成了大量使用Go语言原生开发项目的出现。
下面列举的是原生使用Go语言进行开发的部分项目。
-
Docker项目 网址为https://github.com/docker/docker。 介绍:Docker是一种操作系统层面的虚拟化技术,可以在操作系统和应用程序之间进行隔离,也可以称之为容器。Docker可以在一台物理服务器上快速运行一个或多个实例。例如,启动一个CentOS操作系统,并在其内部命令行执行指令后结束,整个过程就像自己在操作系统一样高效。
-
golang项目 网址为https://github.com/golang/go。 介绍:Go语言的早期源码使用C语言和汇编语言写成。从Go 1.5版本自举后,完全使用Go语言自身进行编写。Go语言的源码对了解Go语言的底层调度有极大的参考意义,建议希望对Go语言有深入了解的读者读一读。
-
Kubernetes项目 网址为https://github.com/kubernetes/kubernetes。 介绍:Google公司开发的构建于Docker之上的容器调度服务,用户可以通过Kubernetes集群进行云端容器集群管理。
-
etcd项目 网址为https://github.com/coreos/etcd。 介绍:一款分布式、可靠的KV存储系统,可以快速进行云配置。
-
beego项目 网址为https://github.com/astaxie/beego。 介绍:beego是一个类似Python的Tornado框架,采用了RESTFul的设计思路,使用Go语言编写的一个极轻量级、高可伸缩性和高性能的Web应用框架。
-
martini项目 网址为https://github.com/go-martini/martini。 介绍:一款快速构建模块化的Web应用的Web框架。
-
codis项目 网址为https://github.com/CodisLabs/codis。 介绍:国产的优秀分布式Redis解决方案。
-
delve项目 网址为https://github.com/derekparker/delve。 介绍:Go语言强大的调试器,被很多集成环境和编辑器整合。
怎样安装Go语言开发包
要学Go语言,首先要学会Go语言开发包的安装和使用。
Go语言的开发包可以在以下站点下载。
- golang中国,网址为https://www.golangtc.com/download;
- Go语言官方网站,网址为https://golang.org/dl/。
Windows安装
Windows 下可以使用 .msi 后缀(在下载列表中可以找到该文件,如go1.4.2.windows-amd64.msi)的安装包来安装。
将上一步选好的安装包下载到本地。
双击下载好的文件,然后按照步骤安装即可。
默认情况下 .msi 文件会安装在 c:\Go 目录下。你可以将 c:\Go\bin 目录添加到 Path 环境变量中。添加后你需要重启命令窗口才能生效。
Linux下安装
如果不是要在Linux平台敲go代码就不需要在Linux平台安装Go,我们开发机上写好的go代码只需要跨平台编译(详见文章末尾的跨平台编译)好之后就可以拷贝到Linux服务器上运行了,这也是go程序跨平台易部署的优势。
Mac下安装
下载可执行文件版,直接点击下一步安装即可,默认会将go安装到/usr/local/go目录下。
检查
上一步安装过程执行完毕后,可以打开终端窗口,输入go version命令,查看安装的Go版本。
go version go1.18.3 windows/amd64
配置GOPATH
GOPATH是一个环境变量,用来表明你写的go项目的存放路径
GOPATH路径最好只设置一个,所有的项目代码都放到GOPATH的src目录下。
Linux和Mac平台就参照上面配置环境变量的方式将自己的工作目录添加到环境变量中即可。 Windows平台按下面的步骤将(你的安装目录,例如:D:\go)添加到环境变量:
go的项目目录
在进行Go语言开发的时候,我们的代码总是会保存在$GOPATH/src目录下。在工程经过go build、go install或go get等指令后,会将下载的第三方包源代码文件放在$GOPATH/src目录下, 产生的二进制可执行文件放在 $GOPATH/bin目录下,生成的中间缓存文件会被保存在 $GOPATH/pkg 下。
如果我们使用版本管理工具(Version Control System,VCS。常用如Git)来管理我们的项目代码时,我们只需要添加$GOPATH/src目录的源代码即可。bin 和 pkg 目录的内容无需版本控制。
目前流行的项目结构
Go语言中也是通过包来组织代码文件,我们可以引用别人的包也可以发布自己的包,但是为了防止不同包的项目名冲突,我们通常使用顶级域名来作为包名的前缀,这样就不担心项目名冲突的问题了。
因为不是每个个人开发者都拥有自己的顶级域名,所以目前流行的方式是使用个人的github用户名来区分不同的包。
举个例子:张三和李四都有一个名叫studygo的项目,那么这两个包的路径就会是:
import "github.com/zhangsan/studygo"
import "github.com/lisi/studygo"
以后我们从github上下载别人包的时候,如:
go get github.com/jmoiron/sqlx
那么,这个包会下载到我们本地GOPATH目录下的src/github.com/jmoiron/sqlx。
Hello World
在src目录下创建一个hello目录,在hello目录中创建一个main.go文件:
package main // 声明 main 包,表明当前是一个可执行程序
import "fmt" // 导入内置 fmt
func main(){ // main函数,是程序执行的入口
fmt.Println("Hello World!") // 在终端打印 Hello World!
}
在hello目录下执行:go build
go编译器会去 GOPATH的src目录下查找你要编译的hello项目
编译得到的可执行文件会保存在执行编译命令的当前目录下,如果是windows平台会在当前目录下找到hello.exe可执行文件。
在终端直接执行该hello.exe文件:
d:\go\src\hello>hello.exe
Hello World!
我们还可以使用-o参数来指定编译后可执行文件的名字。
go build -o heiheihei.exe
##问题:当go get的时候报错如下
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
解决办法
开启go modules功能,命令行输入
go env -w GO111MODULE=on
在该项目目录下,初始化Go moudle,运行下面命令
go mod init xxx //xxx代表文件夹名
命令
假如你已安装了golang环境,你可以在命令行执行go命令查看相关的Go语言命令:
$ go
Go is a tool for managing Go source code.
Usage:
go command [arguments]
The commands are:
build compile packages and dependencies
clean remove object files
doc show documentation for package or symbol
env print Go environment information
bug start a bug report
fix run go tool fix on packages
fmt run gofmt on package sources
generate generate Go files by processing source
get download and install packages and dependencies
install compile and install packages and dependencies
list list packages
run compile and run Go program
test test packages
tool run specified go tool
version print Go version
vet run go tool vet on packages
Use "go help [command]" for more information about a command.
Additional help topics:
c calling between Go and C
buildmode description of build modes
filetype file types
gopath GOPATH environment variable
environment environment variables
importpath import path syntax
packages description of package lists
testflag description of testing flags
testfunc description of testing functions
Use "go help [topic]" for more information about that topic.
go env用于打印Go语言的环境信息。
go run命令可以编译并运行命令源码文件。
go get可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并对它们进行编译和安装。
go build命令用于编译我们指定的源码文件或代码包以及它们的依赖包。
go install用于编译并安装指定的代码包及它们的依赖包。
go clean命令会删除掉执行其它命令时产生的一些文件和目录。
go doc命令可以打印附于Go语言程序实体上的文档。我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的。
go test命令用于对Go语言编写的程序进行测试。
go list命令的作用是列出指定的代码包的信息。
go fix会把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码。
go vet是一个用于检查Go语言源码中静态错误的简单工具。
go tool pprof命令来交互式的访问概要文件的内容。