GO的执行原理以及GO命令

Go的执行原理以及Go的命令

1、Go的源码文件

Go 的源码文件分类:node

yuanmawenjian1

如上图,分为三类:git

一、命令源码文件:github

声明本身属于 main 代码包、包含无参数声明和结果声明的 main 函数。golang

命令源码文件被安装之后,GOPATH 若是只有一个工做区,那么相应的可执行文件会被存放当前工做区的 bin 文件夹下;若是有多个工做区,就会安装到 GOBIN 指向的目录下。算法

命令源码文件是 Go 程序的入口。shell

同一个代码包中最好也不要放多个命令源码文件。多个命令源码文件虽然能够分开单独 go run 运行起来,可是没法经过 go build 和 go install。浏览器

咱们先打开上次课的hello目录,而后复制helloworld.go为helloworld2.go文件,并修改里面的内容:安全

package main
import "fmt"
func main(){
    fmt.Println("我是第二个helloworld文件")
    fmt.Print("Go Go Go !!!")
}

hello目录下有两个go文件了,一个是helloworld.go,一个是helloworld2.go。先说明一下,在上述文件夹中放了两个命令源码文件,同时都声明本身属于 main 代码包。ruby

gomingling1

打开终端,进入hello这个目录,也能够看到这两个文件:网络

localhost:~ ruby cd go/src/hello
localhost:hello ruby ls
helloworld.go   helloworld2.go

而后咱们分别执行go run命令,能够看到两个go文件均可以被执行:

localhost:hello ruby$ go run helloworld.go
HelloWorld
Go Go Go !!!localhost:hello ruby$ go run helloworld2.go
我是第二个helloworld文件
Go Go Go !!!

gomingling2

接下来执行 go build 和 go install ,看看会发生什么:

localhost:hello ruby$ go build 
# hello
./helloworld2.go:3:6: main redeclared in this block
    previous declaration at ./helloworld.go:3:6
localhost:hello ruby$ go install
# hello
./helloworld2.go:3:6: main redeclared in this block
    previous declaration at ./helloworld.go:3:6
localhost:hello ruby$

运行效果图:

gomingling3

这也就证实了多个命令源码文件虽然能够分开单独 go run 运行起来,可是没法经过 go build 和 go install。

同理,若是命令源码文件和库源码文件也会出现这样的问题,库源码文件不能经过 go build 和 go install 这种常规的方法编译和安装。具体例子和上述相似,这里就再也不贴代码了。

因此命令源码文件应该是被单独放在一个代码包中。

二、库源码文件

库源码文件就是不具有命令源码文件上述两个特征的源码文件。存在于某个代码包中的普通的源码文件。

库源码文件被安装后,相应的归档文件(.a 文件)会被存放到当前工做区的 pkg 的平台相关目录下。

三、测试源码文件

名称以 _test.go 为后缀的代码文件,而且必须包含 Test 或者 Benchmark 名称前缀的函数:

func TestXXX( t *testing.T) {
 
}

名称以 Test 为名称前缀的函数,只能接受 *testing.T 的参数,这种测试函数是功能测试函数。

func BenchmarkXXX( b *testing.B) {
 
}

名称以 Benchmark 为名称前缀的函数,只能接受 *testing.B 的参数,这种测试函数是性能测试函数。

如今答案就很明显了:

命令源码文件是能够单独运行的。可使用 go run 命令直接运行,也能够经过 go build 或 go install 命令获得相应的可执行文件。因此命令源码文件是能够在机器的任何目录下运行的。

举个栗子:

好比平时咱们在 LeetCode 上刷算法题,这时候写的就是一个程序,这就是命令源码文件,能够在电脑的任意一个文件夹新建一个 go 文件就能够开始刷题了,写完就能够运行,对比执行结果,答案对了就能够提交代码。

可是公司项目里面的代码就不能这样了,只能存放在 GOPATH 目录下。由于公司项目不可能只有命令源码文件的,确定是包含库源码文件,甚至包含测试源码文件的。

2、Go的命令

目前Go的最新版1.12里面基本命令有如下17个。

咱们能够打开终端输入:go help便可看到Go的这些命令以及简介。

bug         start a bug report
    build       compile packages and dependencies
    clean       remove object files and cached files
    doc         show documentation for package or symbol
    env         print Go environment information
    fix         update packages to use new APIs
    fmt         gofmt (reformat) 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 or modules
    mod         module maintenance
    run         compile and run Go program
    test        test packages
    tool        run specified go tool
    version     print Go version
    vet         report likely mistakes in packages

其中和编译相关的有build、get、install、run这4个。接下来就依次看看这四个的做用。

在详细分析这4个命令以前,先罗列一下通用的命令标记,如下这些命令均可适用的:

名称 说明
-a 用于强制从新编译全部涉及的 Go 语言代码包(包括 Go 语言标准库中的代码包),即便它们已是最新的了。该标记可让咱们有机会经过改动底层的代码包作一些实验。
-n 使命令仅打印其执行过程当中用到的全部命令,而不去真正执行它们。若是不仅想查看或者验证命令的执行过程,而不想改变任何东西,使用它正好合适。
-race 用于检测并报告指定 Go 语言程序中存在的数据竞争问题。当用 Go 语言编写并发程序的时候,这是很重要的检测手段之一。
-v 用于打印命令执行过程当中涉及的代码包。这必定包括咱们指定的目标代码包,而且有时还会包括该代码包直接或间接依赖的那些代码包。这会让你知道哪些代码包被执行过了。
-work 用于打印命令执行时生成和使用的临时工做目录的名字,且命令执行完成后不删除它。这个目录下的文件可能会对你有用,也能够从侧面了解命令的执行过程。若是不添加此标记,那么临时工做目录会在命令执行完毕前删除。
-x 使命令打印其执行过程当中用到的全部命令,并同时执行它们。

1. go run

专门用来运行命令源码文件的命令,注意,这个命令不是用来运行全部 Go 的源码文件的!

go run 命令只能接受一个命令源码文件以及若干个库源码文件(必须同属于 main 包)做为文件参数,且不能接受测试源码文件。它在执行时会检查源码文件的类型。若是参数中有多个或者没有命令源码文件,那么 go run 命令就只会打印错误提示信息并退出,而不会继续执行。

这个命令具体干了些什么事情呢?来分析分析,咱们先从新建立一个新文件:mytest.go,并加入如下代码:

package main
import "fmt"
func main(){
    fmt.Println("HelloWorld")
    fmt.Println("你好,Go!!!")
}

执行go run 配合-n:

localhost:hello ruby$ go run -n mytest.go 
 
#
# command-line-arguments
#
 
mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
packagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.a
EOF
cd /Users/ruby/go/src/hello
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid ieg41NOobNF0eqq3xgnP/ieg41NOobNF0eqq3xgnP -dwarf=false -goversion go1.12.1 -D _/Users/ruby/go/src/hello -importcfg $WORK/b001/importcfg -pack -c=4 ./mytest.go
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
... # 此处省略
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/mytest -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=vpgT856LhbZPXp6WeHib/ieg41NOobNF0eqq3xgnP/ieg41NOobNF0eqq3xgnP/vpgT856LhbZPXp6WeHib -extld=clang $WORK/b001/_pkg_.a
$WORK/b001/exe/mytest
localhost:hello ruby$

运行效果图:

gomingling4

这里能够看到建立了两个临时文件夹 b001 和 exe,先执行了 compile 命令,而后 link,生成了归档文件.a 和 最终可执行文件,最终的可执行文件放在 exe 文件夹里面。命令的最后一步就是执行了可执行文件。

总结一下以下图:

gomingling5

举个例子,生成的临时文件能够用go run -work看到,好比当前生成的临时文件夹是以下的路径:

localhost:hello ruby$ go run -work mytest.go 
WORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496
HelloWorld
你好,Go!!!
localhost:hello ruby$

咱们进入:/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496目录,能够看到以下目录结构:

gomingling6

能够看到,最终go run命令是生成了2个文件,一个是归档文件,一个是可执行文件。

go run 命令在第二次执行的时候,若是发现导入的代码包没有发生变化,那么 go run 不会再次编译这个导入的代码包。直接静态连接进来。

localhost:hello ruby$ go run -n mytest.go 
mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile command-line-arguments=/Users/ruby/Library/Caches/go-build/6b/6b9577027c8da20b0ae6da790267f558b3b71eea1feb44039fb933b35eaef6f9-d
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
...
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/mytest -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=goiqf_1cemqljgOYzSRA/ieg41NOobNF0eqq3xgnP/MVbHdxOky1BGK6Aq_4bM/goiqf_1cemqljgOYzSRA -extld=clang /Users/ruby/Library/Caches/go-build/6b/6b9577027c8da20b0ae6da790267f558b3b71eea1feb44039fb933b35eaef6f9-d
$WORK/b001/exe/mytest
localhost:hello ruby$

2. go build

go build 命令主要是用于测试编译。在包的编译过程当中,如有必要,会同时编译与之相关联的包。

  1. 若是是普通包,当你执行go build命令后,不会产生任何文件。
  2. 若是是main包,当只执行go build命令后,会在当前目录下生成一个可执行文件。若是须要在$GOPATH/bin目录下生成相应的exe文件,须要执行go install 或者使用 go build -o 路径/可执行文件。
  3. 若是某个文件夹下有多个文件,而你只想编译其中某一个文件,能够在 go build 以后加上文件名,例如 go build a.go;go build 命令默认会编译当前目录下的全部go文件。
  4. 你也能够指定编译输出的文件名。好比,咱们能够指定go build -o 可执行文件名,默认状况是你的package名(非main包),或者是第一个源文件的文件名(main包)。
  5. go build 会忽略目录下以”_”或者”.”开头的go文件。
  6. 若是你的源代码针对不一样的操做系统须要不一样的处理,那么你能够根据不一样的操做系统后缀来命名文件。

当代码包中有且仅有一个命令源码文件的时候,在文件夹所在目录中执行 go build 命令,会在该目录下生成一个与目录同名的可执行文件。

// 假设当前文件夹名叫 hello
localhost:hello ruby$ pwd
/Users/ruby/go/src/hello
localhost:hello ruby$ ls
helloworld.go
localhost:hello ruby$ go build
localhost:hello ruby$ ls
hello       helloworld.go
localhost:hello ruby$

因而在当前目录直接生成了以当前文件夹为名的可执行文件( 在 Mac 平台下是 Unix executable 文件,在 Windows 平台下是 exe 文件)

gomingling7

可是这种状况下,若是使用 go install 命令,若是 GOPATH 里面只有一个工做区,就会在当前工做区的 bin 目录下生成相应的可执行文件。若是 GOPATH 下有多个工做区,则是在 GOBIN 下生成对应的可执行文件。

localhost:hello ruby$ go install
go install hello: open /usr/local/go/bin/hello: permission denied
localhost:hello ruby$

gomingling8

这个问题是由于它须要建立bin目录,而后把可刚才的可执行文件放进去,而目前咱们在gopath下尚未bin目录,那么就须要先建立这个文件,而普通用户没有直接建立文件夹的权限,这个和Go语言的命令是没有关系的。咱们能够加上sodu 来执行这个命令,表示使用管理员的身份执行,而后输入密码,那么就能够建立bin这个文件夹了。

再次执行:

localhost:hello ruby$ sudo go install
Password:
localhost:hello ruby$

执行完 go install 会发现可执行文件不见了!去哪里了呢?实际上是被移动到了 bin 目录下了(若是 GOPATH 下有多个工做区,就会放在GOBIN 目录下)。

查看目录:

gomingling9

那 go build 和 go install 究竟干了些什么呢?

先来讲说 go build。go build 用于编译咱们指定的源码文件或代码包以及它们的依赖包。可是注意若是用来编译非命令源码文件,即库源码文件,go build 执行完是不会产生任何结果的。这种状况下,go build 命令只是检查库源码文件的有效性,只会作检查性的编译,而不会输出任何结果文件。

go build 编译命令源码文件,则会在该命令的执行目录中生成一个可执行文件,上面的例子也印证了这个过程。

go build 后面不追加目录路径的话,它就把当前目录做为代码包并进行编译。go build 命令后面若是跟了代码包导入路径做为参数,那么该代码包及其依赖都会被编译。

go build 命令究竟作了些什么呢?咱们能够执行-n这个命令来查看:

localhost:hello ruby$ go build -n
 
#
# hello
#
 
mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
packagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.a
EOF
cd /Users/ruby/go/src/hello
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid PXDetO1R1NhLFMK5QGUc/PXDetO1R1NhLFMK5QGUc -goversion go1.12.1 -D "" -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile hello=$WORK/b001/_pkg_.a
...
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=diTh1q6kcbGRIX3aj3mU/PXDetO1R1NhLFMK5QGUc/PXDetO1R1NhLFMK5QGUc/diTh1q6kcbGRIX3aj3mU -extld=clang $WORK/b001/_pkg_.a
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out hello
localhost:hello ruby$

能够看到,执行过程和 go run 大致相同,惟一不一样的就是在最后一步,go run 是执行了可执行文件,可是 go build 命令,只是把库源码文件编译了一遍,而后把可执行文件移动到了当前目录的文件夹中。

总结一下以下图:

gomingling10

3. go install

go install 命令是用来编译并安装代码包或者源码文件的。

go install 命令在内部实际上分红了两步操做:第一步是生成结果文件(可执行文件或者.a包),第二步会把编译好的结果移到$GOPATH/pkg或者​$GOPATH/bin

可执行文件: 通常是 go install 带main函数的go文件产生的,有函数入口,全部能够直接运行。

.a应用包: 通常是 go install 不包含main函数的go文件产生的,没有函数入口,只能被调用。

go install 用于编译并安装指定的代码包及它们的依赖包。当指定的代码包的依赖包尚未被编译和安装时,该命令会先去处理依赖包。与 go build 命令同样,传给 go install 命令的代码包参数应该以导入路径的形式提供。而且,go build 命令的绝大多数标记也均可以用于
实际上,go install 命令只比 go build 命令多作了一件事,即:安装编译后的结果文件到指定目录。

安装代码包会在当前工做区的 pkg 的平台相关目录下生成归档文件(即 .a 文件)。
安装命令源码文件会在当前工做区的 bin 目录(若是 GOPATH 下有多个工做区,就会放在 GOBIN 目录下)生成可执行文件。

一样,go install 命令若是后面不追加任何参数,它会把当前目录做为代码包并安装。这和 go build 命令是彻底同样的。

go install 命令后面若是跟了代码包导入路径做为参数,那么该代码包及其依赖都会被安装。

go install 命令后面若是跟了命令源码文件以及相关库源码文件做为参数的话,只有这些文件会被编译并安装。

go install 命令究竟作了些什么呢?

localhost:hello ruby$ go install -n
 
#
# hello
#
 
mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
packagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.a
EOF
cd /Users/ruby/go/src/hello
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT -goversion go1.12.1 -D "" -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile hello=$WORK/b001/_pkg_.a
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
...
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=FJ6kJTmN9rcWcwLhqfiQ/E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT/FJ6kJTmN9rcWcwLhqfiQ -extld=clang $WORK/b001/_pkg_.a
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mkdir -p /usr/local/go/bin/
mv $WORK/b001/exe/a.out /usr/local/go/bin/hello
localhost:hello ruby$

前面几步依旧和 go run 、go build 彻底一致,只是最后一步的差异,go install 会把命令源码文件安装到当前工做区的 bin 目录(若是 GOPATH 下有多个工做区,就会放在 GOBIN 目录下)。若是是库源码文件,就会被安装到当前工做区的 pkg 的平台相关目录下。

总结一下以下图:

gomingling11

在安装多个库源码文件时有可能遇到以下的问题:

localhost:hello ruby$  go install envir.go fpath.go ipath.go pnode.go util.go
go install: no install location for .go files listed on command line (GOBIN not set)

并且,在咱们为环境变量 GOBIN 设置了正确的值以后,这个错误提示信息仍然会出现。这是由于,只有在安装命令源码文件的时候,命令程序才会将环境变量 GOBIN 的值做为结果文件的存放目录。而在安装库源码文件时,在命令程序内部的表明结果文件存放目录路径的那个变量不会被赋值。最后,命令程序会发现它依然是个无效的空值。因此,命令程序会一样返回一个关于“无安装位置”的错误。这就引出一个结论,咱们只能使用安装代码包的方式来安装库源码文件,而不能在 go install 命令罗列并安装它们。另外,go install 命令目前没法接受标记-o以自定义结果文件的存放位置。这也从侧面说明了
go install 命令不支持针对库源码文件的安装操做。

4. go get

go get 命令用于从远程代码仓库(好比 Github )上下载并安装代码包。注意,go get 命令会把当前的代码包下载到 $GOPATH 中的第一个工做区的 src 目录中,并安装。

使用 go get 下载第三方包的时候,依旧会下载到 $GOPATH 的第一个工做空间,而非 vendor 目录。当前工做链中并无真正意义上的包依赖管理,不过好在有很多第三方工具可选。

若是在 go get 下载过程当中加入-d 标记,那么下载操做只会执行下载动做,而不执行安装动做。好比有些很是特殊的代码包在安装过程当中须要有特殊的处理,因此咱们须要先下载下来,因此就会用到-d 标记。

还有一个颇有用的标记是-u标记,加上它能够利用网络来更新已有的代码包及其依赖包。若是已经下载过一个代码包,可是这个代码包又有更新了,那么这时候能够直接用-u标记来更新本地的对应的代码包。若是不加这个-u标记,执行 go get 一个已有的代码包,会发现命令什么都不执行。只有加了-u标记,命令会去执行 git pull 命令拉取最新的代码包的最新版本,下载并安装。

命令 go get 还有一个很值得称道的功能——智能下载。在使用它检出或更新代码包以后,它会寻找与本地已安装 Go 语言的版本号相对应的标签(tag)或分支(branch)。好比,本机安装 Go 语言的版本是1.x,那么 go get 命令会在该代码包的远程仓库中寻找名为 “go1” 的标签或者分支。若是找到指定的标签或者分支,则将本地代码包的版本切换到此标签或者分支。若是没有找到指定的标签或者分支,则将本地代码包的版本切换到主干的最新版本。

go get 经常使用的一些标记以下:

标记名称 标记描述
-d 让命令程序只执行下载动做,而不执行安装动做。
-f 仅在使用-u标记时才有效。该标记会让命令程序忽略掉对已下载代码包的导入路径的检查。若是下载并安装的代码包所属的项目是你从别人那里 Fork 过来的,那么这样作就尤其重要了。
-fix 让命令程序在下载代码包后先执行修正动做,然后再进行编译和安装。
-insecure 容许命令程序使用非安全的 scheme(如 HTTP )去下载指定的代码包。若是你用的代码仓库(如公司内部的 Gitlab )没有HTTPS 支持,能够添加此标记。请在肯定安全的状况下使用它。
-t 让命令程序同时下载并安装指定的代码包中的测试源码文件中依赖的代码包。
-u 让命令利用网络来更新已有代码包及其依赖包。默认状况下,该命令只会从网络上下载本地不存在的代码包,而不会更新已有的代码包。

go get 命令究竟作了些什么呢?咱们仍是来打印一下每一步的执行过程。

localhost:hello ruby$ go get -x github.com/go-errors/errors
cd .
git clone https://github.com/go-errors/errors /Users/ruby/go/src/github.com/go-errors/errors
cd /Users/ruby/go/src/github.com/go-errors/errors
git submodule update --init --recursive
cd /Users/ruby/go/src/github.com/go-errors/errors
git show-ref
cd /Users/ruby/go/src/github.com/go-errors/errors
git submodule update --init --recursive
WORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build188558329
localhost:hello ruby$

效果图:

gomingling12

这里能够很明显的看到,执行完 go get 命令之后,会调用 git clone 方法下载源码,并编译,最终会把库源码文件编译成归档文件安装到 pkg 对应的相关平台目录下。

gomingling13

总结一下以下图:

gomingling14

5. 其余命令

go clean

go clean 命令是用来移除当前源码包里面编译生成的文件,这些文件包括

  • _obj/ 旧的object目录,由Makefiles遗留
  • _test/ 旧的test目录,由Makefiles遗留
  • _testmain.go 旧的gotest文件,由Makefiles遗留
  • test.out 旧的test记录,由Makefiles遗留
  • build.out 旧的test记录,由Makefiles遗留
  • *.[568ao] object文件,由Makefiles遗留
  • DIR(.exe) 由 go build 产生
  • DIR.test(.exe) 由 go test -c 产生
  • MAINFILE(.exe) 由 go build MAINFILE.go产生

go fmt

go fmt 命令主要是用来帮你格式化所写好的代码文件。

好比咱们写了一个格式很糟糕的 test.go 文件,咱们只须要使用 fmt go test.go 命令,就可让go帮咱们格式化咱们的代码文件。可是咱们通常不多使用这个命令,由于咱们的开发工具通常都带有保存时自动格式化功能,这个功能底层其实就是调用了 go fmt 命令而已。

使用go fmt命令,更多时候是用gofmt,并且须要参数-w,不然格式化结果不会写入文件。gofmt -w src,能够格式化整个项目。

go test

go test 命令,会自动读取源码目录下面名为*_test.go的文件,生成并运行测试用的可执行文件。默认的状况下,不须要任何的参数,它会自动把你源码包下面全部test文件测试完毕,固然你也能够带上参数,详情请参考go help testflag

go doc

go doc 命令其实就是一个很强大的文档工具。

如何查看相应package的文档呢? 例如builtin包,那么执行go doc builtin;若是是http包,那么执行go doc net/http;查看某一个包里面的函数,那么执行go doc fmt Printf;也能够查看相应的代码,执行go doc -src fmt Printf;

# 查看net/http包
localhost:hello ruby$ go doc net/http
# 查看time包
localhost:hello ruby$ go doc time
# 查看某个包里的指定函数
localhost:hello ruby$ go doc fmt Printf

经过命令在命令行执行 go doc -http=:端口号,好比godoc -http=:8080。而后在浏览器中打开127.0.0.1:8080,你将会看到一个golang.org的本地copy版本,经过它你能够查询pkg文档等其它内容。若是你设置了GOPATH,在pkg分类下,不但会列出标准包的文档,还会列出你本地GOPATH中全部项目的相关文档,这对于常常被限制访问的用户来讲是一个不错的选择。

localhost:hello ruby$ godoc -http=:9527

go fix 用来修复之前老版本的代码到新版本,例如go1以前老版本的代码转化到go1

go version 查看go当前的版本

go env 查看当前go的环境变量

go list 列出当前所有安装的package

相关文章
相关标签/搜索