7e347c01e7b5b0ece1a6e3e8758cbff2.png
知乎专栏:Go开发深入详解 知乎ID: Zarten 简介: 互联网一线工作者,尊重原创并欢迎评论留言指出不足之处,也希望多些关注和点赞是给作者最好的鼓励 !

概述

Go语言有一套完整的操作命令,非常实用,掌握它可以事半功倍。

将详细讲解以下命令(便于快速查找):

  • go bug
  • go build
  • go install
  • go get
  • go mod
  • go run
  • go clean
  • go fmt
  • go list
  • go version
  • go env

直接输入go,给出了全部命令,如下所示:

go
0525799248e5a07904bc8d5c67b89499.png

若想更加详细了解某个命令的具体用法,只需输入"go help 命令",例如:

go help build
45710cd15ea5514eedc182c0da9dabbd.png

从上面可看到描述非常详细。同时官方也给出了非常详细的文档说明。

下面将详细介绍一些命令。

go bug

输入此命名后会直接打开默认浏览器,显示go的github页面进行bug报告,并会自动添加系统的信息。

go bug
6b4e66e35475924670ab57a6ea89eabc.png

go build

此命令用于编译指定的源码文件或代码包及依赖包。

目录如下所示:

1498dedefb916d4083bc67ddb0a02f7a.png

若只有一个main函数文件,进入main函数所在目录,直接输入"go build"会自动编译main函数所在文件,并生成一个可执行文件。

go build
8539697df999424f653048d34cd27ec1.png

若要指定文件名,可使用参数 -o,也可指定文件输出的目录。

go build -o main.exe
d308308d11ade26a2ff8ee8deb527960.png

若有多个main函数文件,若只想编译其中某个文件,可在go build 后加入文件名即可,如:"go build 文件名"

main2.go中也有一个main函数,若直接输入"go build"会编译出错:

go build
caccd0c291111419324158051d82e5b1.png

此时需要"go build 文件名"指定一个文件名编译:

go build main2.go
7df427bb287934760a6775c97040df99.png

若是在普通包下,输入"go build"后不会生成任何文件,只会检查错误。如下zarten为一个普通包,在此包下执行"go build"

go build
59fc4e6aa15b97cd0f8edbc0a8c027d4.png

除了"-o"参数,还有一些其他参数:

-ogo build -o a/b/c-igo install-a-n-p n-race-v-work-x-n-ccflags 'arg list'-compiler name-gccgoflags 'arg list'-gcflags 'arg list'-installsuffix suffix-race-installsuffix race-n-ldflags 'flag list'-tags 'tag list'

例如"-n"参数:

go build -n main.go
ed2665bcd0081a8c1a9385016917cd1e.png

go install

go install 跟 go build 类似,只是多做了一件事就是安装编译后的文件到指定目录。

go install main.go
de832f1980a58d2f6c1654cf9aee2fc4.png

出现错误:“go install: no install location for .go files listed on command line (GOBIN not set)”

这是因为没有设置环境变量GOBIN。

Go开发中一般要设置环境变量GOROOT和GOPATH。按照Go开发规范,GOPATH目录下一般分为三个子目录:src、pkg、bin

src:源代码文件

pkg:编译后的库静态文件

bin:源代码编译后的可执行文件

因此环境变量GOBIN设置的就是上面的bin目录,"go install"命令就将可执行文件自动安装到bin目录下。

设置环境变量GOBIN

export GOBIN=$GOPATH/bin
7f73a8e4d0e0c3ea0c191bc37d0dc4b3.png

设置成功后再来执行上面的go install命令。

go install main.go
be12fc595425444158bd7c8d024c8d97.png

上图看到,执行后可执行文件自动安装到bin目录下了。

go install的参数跟go build一样,这里不再说明。

go get

go get命令用于动态获取远程代码包及其依赖包,并进行编译和安装。

执行命令后一般会下载在GOPATH的src目录下。

go get github.com/PuerkitoBio/goquery
566c0bf6128bbff28fb7f83cb0f42ab6.png

当想要修改package的版本时,只需要go get package@指定的version即可

上图所示,无法下载“golang.org”网站内容,这是由于国内网络限制原因,当出现这种情况一般有3种方法解决:

1.手动下载

2.设置代理

3.使用GOPROXY环境变量

1.手动下载方式,不推荐,因为可能有太多的依赖(或依赖的依赖)关系。

2.设置代理

若你有代理,可以使用如下命令

export http_proxy=http://proxyAddress:port
export https_proxy=http://proxyAddress:port

export all_proxy=http://proxyAddress:port

3.使用GOPROXY环境变量

推荐使用这种方法,但前提是Go版本是1.11及以后。

所以需要设置GOPROXY环境变量,设置后下载源码将通过这个环境变量设置的代理地址进行下载。

goproxy.io这个开源项目帮我们实现了代理功能,并提供了公用的代理服务:

https://goproxy.io
  • 设置GOPROXY

使用公用代理服务https://goproxy.io

export GOPROXY=https://goproxy.io

由于需要依赖go module功能,所以需要开启MODULE

export GO111MODULE=on

最后再来执行上面的go get命令:

go get github.com/PuerkitoBio/goquery
de59be2fd892d1bddaf576fc130b1de4.png

不过这种方法下载的包源码在GOPATH目录下的pkg/mod目录下。

若需要关闭GOPROXY环境变量,只需:

export GOPROXY=

另外,国内开源项目goproxy.cn也提供了类似服务,公用代理服务:https://goproxy.cn

go get参数说明

go get有一些参数,如下所示:

e17b51b2e85c409d0fc57ce8d3325c2c.png

go mod

go mod 是 go modules的简写,用于对go包的管理。从go1.11开始实现了modules管理,mod相比以前的方式,优点主要体现在:

  • 项目不需要放在GOPATH下的src目录了,可以在任意目录。
  • 自动下载第三方包和依赖包。
  • 第三方包会指定版本号。
  • 项目内会生成一个go.mod文件,文件内指定包依赖关系。
  • 有一些第三方包不存在了或转移到其他地方,不需要改代码,只需用replace命令替换即可。

要使用modules,前提是需要将环境变量GO111MODULE设为on或者auto:

GO111MODULE=on
c9066fcf851a1f81e0fdd77586e29123.png

GO111MODULE有三个值:

  • GO111MODULE=off : go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
  • GO111MODULE=on :go命令行会使用modules,不会去GOPATH目录下查找。
  • GO111MODULE=auto : 这是默认值,会根据当前目录的位置来决定是否启用modules功能,若项目在GOPATH的src之外且根目录下有go.mod文件时会启用modules。

下面将演示如何使用mod来管理项目

  • 在任意目录下创建一个自己的项目

zarten.go

package main

import "fmt"

func main(){
	fmt.Println("Zarten")
}

如下图所示:

9b2cf0dcb7254a1bbbd233b42246e661.png

首先使用"go mod init 模块名" 初始化项目

go mod init my
e9513c98d20dfc4d45d07393dfe6380c.png

上图看到,执行init后在该目录下生成了一个go.mod文件,此时go.mod文件中包含了模块名称和当前go的版本号。

41eafbce0de96a4f94b1a73ef5d61a9f.png
  • 引用第三方包

此时引用第三方包,以beego(一个web服务器)为例,看mod是如何工作的。

package main

import (
	"fmt"
	"github.com/astaxie/beego"
)

func main(){
	fmt.Println("Zarten")
	beego.Run()
}

编写完成后直接"go build zarten.go" 或 "go run zarten.go"命令,go会自动查找依赖关系并下载写入go.mod文件中,并生成go.sum文件(用来检测依赖模块是否被篡改)。

注:若在检测依赖时,由于网络原因需要用代理,在上面有讲解如何使用代理!

go build zarten.go
95f15c85ba7748b9d065019f0632640b.png

此时查看go.mod文件,如下所示:

daea6d9a23e9ab7689672c2b84bb5c1c.png

可以看到require后面是引用的包,并且还指定了包的版本v1.12.2

下载的包保存在了GOPATH/pkg/mod下面,并且可以多版本共存保存。

9b7690f0c8b206e3c3d5b588b3efb910.png

若需要下载不同的版本,需要在go.mod文件的require后面指定版本号。

  • 依赖包地址变更的做法

上面我们说到,mod管理的好处是项目地址变更后无需更改源代码,只需使用replace命令即可。

例如zarten这个包从http://golang.org/x/zarten 移动到了 http://github.com/golang/zarten

在go.mod文件中,使用replace命令如下:

replace golang.org/x/zarten => github.com/golang/zarten latest

另外go mod有如下命令:

d9d419d955ad93ab96e5ef4067c332d1.png

可通过官网查看每个go版本中mod的变化:点击查看

go mod的常见错误问题及解决方案查看这里:

  • 在go modules里使用go get进行包管理
  • go1.13 mod 实践和常见问题

go run

go run用于编译并运行源码文件,由于包含编译步骤,所以go build参数都可用于go run,在go run 中只接受go源码文件而不接受代码包。

go run zarten.go
49393d696b923660e10a67f4f8b7923e.png

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产生
  • *.so 由 SWIG 产生

参数包括:

-i-n-r-x-n

一般使用go clean命令清理干净后上传到代码托管。

执行go clean -i -n 进行清理(根据go版本不同,可能需要mod支持)

go clean -i -n
6bf59d7f5483532beb604ce47922c2f0.png

go fmt

go fmt用于检查并格式化成go语言的规范格式。

我们知道,在go语言中有严格的代码规范,否则编译不通过。不过大部分编译器已经自动实现规范格式,但此命名还是非常有用的。

参数说明:

-l-w-r-s-d-e-cpuprofile

go fmt可以格式化整个项目或某个go文件,一般使用gofmt工具。

例如在my目录下有2个不规范文件:zarten.go 和 zarten2.go

zarten.go

package main

import (
	"fmt"
)

func main() {
				fmt.Println("Zarten")
	fmt.Println("Zarten")

}

zarten2.go

package main

import (
	"fmt"
)

func main() {
fmt.Println("Zarten2") 



 fmt.Println("Zarten2")
}

显示项目内需要格式的文件:

gofmt -l my
4db20d3dab512957e412e1ac1e58d22c.png

加上参数-w,自动写入文件中:

gofmt -l -w my
95561ba359b1253bbafaf0c1dd51c4dd.png

查看文件发现,格式已经改写成规范格式了。

同时gofmt也可对单个文件使用,例如zarten.go

gofmt zarten.go

将规范化的代码打印出来,但没有将规范化写入文件中

e933630ea4d5442322f590bef2208ffc.png

要将写入文件中需要加"-w"参数:

gofmt -w zarten.go

go list

go list 会列出当前安装的包

go list
28c2def5b681164cb37f5733a0e6dc0d.png

go version

go version 可以查看当前go的版本

go version
126fb9c3a599661eb7b1241571d78fe7.png

go env

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

go env
7e2d51fdf16a95d6a56bd9544d720064.png

交叉编译各大平台命令

有时我们需要在某一平台编译出其他平台的可执行文件,go语言也提供了相关的命令或配置

在Mac平台编译:

  • Linux
CGO_ENABLED=0  GOOS=linux  GOARCH=amd64  go build main.go
  • Windows
CGO_ENABLED=0 GOOS=windows  GOARCH=amd64  go  build  main.go

在Linux平台编译:

  • Mac
CGO_ENABLED=0 GOOS=darwin  GOARCH=amd64  go build main.go
  • Windows
CGO_ENABLED=0 GOOS=windows  GOARCH=amd64  go build main.go

在Windows平台编译:

  • Mac
SET CGO_ENABLED=0 SET GOOS=darwin SET GOARCH=amd64 go build main.go

或写成批处理

SET  CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go
  • Linux
SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build main.go

或写成批处理

SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go

在Goland中的设置交叉编译

例如编译在linux下的程序设置:

GOARCH=amd64;GOOS=linux
8b163ca6c1a4033163b44d354503537a.png

总结

上面讲到命令都是非常有用的,还有一些没讲到的可以通过“go”命令查看,具体需要查看哪个命令,可以“go help 命令”。