一文搞定基本环境

199 阅读12分钟

1 准备

这里做简单的备注,若有疑问 可以自行搜索解决。

1.1 下载和安装

下载: code.google.com/p/go

如果没有 gcc

	sudo apt-get install gcc libc6-dev

执行以上指令来安装编译工具。

clone代码及进入代码路径 假设已经位于Go的安装目录 $GO_INSTALL_DIR下

hg clone -u release https://code.google.com/p/go
cd go/src
./all.bash
   

运行all.bash后出现"ALL TESTS PASSED"字样时才算安装成功。

1.2 设置环境

写的代码一般不在GOPATH/src下,也就是说下面的main.go不在GOPATH/src下,也就是说下面的main.go不在GOPATH/src目录下面,同时需要使用另一个module里面的内容。

并且这个module不是标准库,或者说不在GOROOT里(一般我们不会修改GOROOT中的内容)

导入本地包时将报错

            cannot find package "./go/src/restclients/conditions/src"
        

因为经常在 gospace 写代码

第一种方式:设置GO111MODULE="off",然后 设置GOPATH

        go env -w GOPATH=~/data
        或
        go env -w GOPATH=./data/gospace

第二种方式:设置GO111MODULE="on" 使用go mod,如下

        * 检查系统变量 GOPATH,且GOPATH 下不能有 go.mod

        * GOPATH 不能 与GOROOT 最好不要一样
        * GO project 中不要把 go.work  go.mod 放一起
        * 检查路径

设置go path

vim .bashrc # 添加 GOROOT 和 GOPATH

设置默认项目路径,节省磁盘默认安装空间 GOPATH=./data/gospace 设置mod文件保存目录 GOMODCACHE=./data/gospace/pkg/mod

或者在控制台设置环境路径 几个环境变量,

	export GOROOT=$HOME/go
	export GOBIN=$GOROOT/bin
	export PATH=$PATH:$GOBIN

校验安装

	go version

安装路径 设置指定路径 go env -w GOBIN=/path/to/your/bin go env 查看所有go的环境配置路径 GOBIN 即使将要安装的路径

go help environment 识别所有环境变量

2 指令查询

2.1 构建管理

所有加载包信息的命令都是模块感知的

      *  go build

		构建
	go fix
	go generate
		只有标准库中的包和 .go在命令行中指定为文件的包才能被加载、导入和构建。
		无法构建来自其他模块的包,因为没有地方记录模块需求并确保确定性构建。
	go get
		获取,安装缺失的依赖包
		go get [-d] [-t] [-u] [build flags] [packages]
	go install
		go install [build flags] [packages]
	go list -m
		go list -m [-u] [-retracted] [-versions] [list flags] [modules]
		$ go list -m all
		$ go list -m -versions example.com/m
		$ go list -m -json example.com/m@latest-m标志导致go list列出模块而不是包
                    
    *   go run
*	go test
	go vet
		报告包中可能出现的错误 
			用法:
			go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
			Vet 在导入路径命名的包上运行 Go vet 命令。
			有关 vet 及其标志的更多信息,请参阅“go doc cmd/vetgo mod 
		go mod download [-json] [-x] [modules]
		go mod download golang.org/x/mod@v0.2.0go命令在普通执行过程中会根据需要自动下载模块。
		该go mod download命令主要用于预填充模块缓存或加载要由模块代理服务的数据。

		go mod edit
			go mod edit [editing flags] [-fmt|-print|-json] [go.mod]go mod edit命令提供了一个用于编辑和格式化文件的命令行界面,主要供工具和脚本使用。
			go mod edit 只读取一个go.mod文件;它不查找有关其他模块的信息。
			默认情况下,go mod edit读写go.mod主模块的文件,
			但可以在编辑标志后指定不同的目标文件。
		go mod graph
			go mod graph [-go=version]go mod graph命令以文本形式打印模块需求图(应用了替换)。例如:
    *   go mod init
        	例子:初始化包为模块
            // 创建工作区目录
            mkdir workspace && cd workspace
            // 初始化模块 创建一个hello 依赖于 模块的新模块
            // 创建hello模块
            mkdir hello && cd hello
            cd .. && go mod init hello  //初始化工作区 // go mod init 将创建一个 go.mod 里面又关于这个包的名称和依赖的标志

            fmt.Println(stringutil.Reverse("Hello"))
            olleH

    *  go mod tidy
        	加载安装依赖,清理无用信息
        	此命令编辑您的 go.mod 文件以添加必要但缺少的模块。
            它还删除了未提供任何相关包的未使用模块。
            
            在 hello 目录中的命令提示符下,运行 命令同步模块的依赖关系
            添加代码所需但尚未在模块中跟踪的那些。 go mod tidy example.com/hello


    *  go mod vendor
            将依赖本地化到 vendor 目录
    *  go mod verify
        	go mod verify检查 存储在模块缓存中的主模块的依赖关系是否在下载后未被修改。
        	要执行此检查,请对每个下载的模块文件和提取的目录进行哈希处理,
        	然后将这些哈希值与模块首次下载时记录的哈希值进行比较。
        	检查构建列表中的每个模块(可以用 打印)。
        	go mod verify.zip
        	go mod verifygo list -m all
        go mod why
        	go mod why [-m] [-vendor] packages...
			go mod why在导入图中显示从主模块到每个列出的包的最短路径。
			
			go mod why github.com/gin-gonic/gin	
				# github.com/gin-gonic/gin
				web-service-gin/controlers
				github.com/gin-gonic/gin
	   go version -m
	   		go version [-m] [-v] [file ...]
	   		go version报告用于构建命令行中命名的每个可执行文件的 Go 版本。

			如果命令行上没有命名文件,则go version打印其自己的版本信息。
			表中每一行的含义由第一列中的单词决定。

			pathmain:用于构建可执行文件的包的路径。
			mod: 包含main包的模块。这些列分别是模块路径、版本和总和。
			主模块有版本(devel),没有总和。
			dep:提供一个或多个链接到可执行文件的包的模块。格式与mod.
			=>:替换上一行的模块。如果替换是本地目录,则仅列出目录路径(无版本或总和)。
			如果替换是模块版本,则列出路径、版本和总和,与mod和一样dep。被替换的模块没有总和。
       go clean -modcache
       		go clean [-modcache]-modcache标志会导致go clean删除整个 模块缓存,包括版本化依赖项的未打包源代码。
			该-modcacherw标志(被go build其他模块感知命​​令接受)导致模块缓存中的新目录可写。要传递-modcacherw给所有模块感知命​​令,请将其添加到 GOFLAGS变量中。
			GOFLAGS可以在环境中设置或使用go env -w. 例如,下面的命令将其永久设置:

			go env -w GOFLAGS=-modcacherw
			-modcacherw应谨慎使用;开发人员应注意不要更改模块缓存中的文件。go mod verify 可用于检查缓存中的文件是否与主模块 go.sum文件中的哈希匹配。

			如果所有模块都未修改,则go mod verify打印“所有模块已验证”。
			否则,它会报告哪些模块已更改并以非零状态退出。	

命令接受所有模块命令共有的以下标志。

该-mod标志控制是否go.mod可以自动更新以及是否使用vendor目录。

	-mod=mod告诉go命令忽略供应商目录并 自动更新 go.mod,
		例如,当任何已知模块未提供导入的包时。
	-mod=readonly告诉go命令忽略go.mod目录并在需要更新vendor时报告错误。

	-mod=vendor告诉go命令使用该vendor目录。在这种模式下,该go命令不会使用网络或模块缓存。
	默认情况下,如果go版本是或更高版本并且存在go.mod目录,则该命令的行为就像 使用过一样。
	否则,该命令就像 被使用一样。1.14vendorgo-mod=vendorgo-mod=readonly
该-modcacherw标志指示go命令在模块缓存中创建具有读写权限的新目录,而不是将它们设为只读。
	当始终使用此标志时(通常通过 GOFLAGS=-modcacherw在环境中设置或通过运行 go env -w GOFLAGS=-modcacherw),可以使用命令删除模块缓存,例如rm -r无需先更改权限。
	该 go clean -modcache命令可用于删除模块缓存,无论是否-modcacherw使用。
该-modfile=file.mod标志指示go命令读取(并可能写入)替代文件而不是go.mod模块根目录。
	文件名必须以.mod一个名为的文件go.mod必须仍然存在才能确定模块根目录,但它不会被访问。
	指定时 -modfile,还使用备用go.sum文件:其路径是-modfile通过修剪.mod扩展名并附加.sum.
该-workfile标志指示go命令使用提供的go.work文件进入工作区模式以定义工作区。
   如果设置为工作区模式,go.work -workfile off 则禁用。
   如果未提供,该 命令将搜索工作区部分中描述的文件 。

2.2 包管理

模块感知

	大多数go命令可以在Module-aware mode或GOPATHmode 下运行。
	在模块感知模式下,该go命令使用go.mod文件来查找版本依赖项,它通常从模块缓存中加载包,如果缺少模块则下载它们。
	在GOPATH 模式下,该go命令忽略模块;它在vendor 目录中查找并GOPATH查找依赖项。
	GO111MODULE=on   或 off

本地包导入使用项目路径,
原本Go不建议您使用相对导入, 特别是带有 go.mod的包 相对导入导致失败

	go的起始导入路径为: $HOME/go/src
	所以导入路径相对于$GOPATH$GOROOT 环境变量
	比如位于 /home/go/src/lib/common 和 /home/go/src/lib/routers 中的软件包分别以以下方式导入

    	import(
    		"lib/common"
    		"lib/routers"
    		)
        

在1.11版本后可以使用 包初始化 进行相对导入 如有本地项目

    	go_project/
    		01_hello
    			main.go
    		02_dothings
    		 	utils
    		 		util.go
    		 	main
    		 		main.go

*** 在go_start/目录下

    	go mod init go_project

*** 然后在 各应用中可以导入本地包

02_dothings
    		main.go
    			import (
			          "go_project/02_dothings/utils" //相对导入 
			           "fmt"
			)

mod
    go.mod
	快速指南
    https://go.dev/ref/mod

版本查询和更新

有几个命令允许您使用版本查询指定模块的版本,版本查询出现在@命令行上模块或包路径后面的字符之后。

		例子:

		go get example.com/m@latest
		go mod download example.com/m@master
		go list -m -json example.com/m@e3702bed2
		 go list -m github.com/gin-gonic/gin 
			github.com/gin-gonic/gin v1.7.7
		除了对特定命名版本或修订的查询外,所有查询都考虑由go list -m -versions(见go list -m)报告的可用版本
    

依赖版本控制

        go 使用MVS算法 选择一组模块 版本在构建包时使用。
		https://research.swtch.com/vgo-mvs
		从概念上讲,MVS在模块的有向图运行,由go.mod 指定。 图的每个顶点代表一个模块版本。

		每条变代表一个依赖项的最低要求版本。 使用require指令指定。 该图可由主模块文件的指令exclude 和 文件 replace执行修改
		MVS生成构建列表作为输出,用于构建模块版本列表,
		MVS 从主要模块开始并遍历图,跟踪每个模块所需的最高版本,遍历结束时,最高要求的版本构成构建列表
		它们是满足所有要求的最低版本。
			go list -m all
		该指令检查构建列表。 构建列表不保持在锁定文件中。MVS是确定的,并且发布新版本的依赖时构建列表不会更改。
		因此MVS用于每个模块感知命令开始时计算它。
		MVS 访问并加载 go.mod以蓝色突出显示的每个模块版本文件。
		在图遍历结束时,MVS返回包含粗体版本的构建列表
			A 1.2  B 1.2 C 1.4 ...
    

关键字

区分go.mod文件中不同类型的指令。允许的关键字是

		module, 
			主模块路径,go.mod 必须包含一个module指令, module service
		go, 
			go lost -m -u 检查构建列表中所有已弃用模块的信息。
			go get 检查构建命令行的命名包所需的已弃用模块。
		require, 
			require指令声明给定模块依赖项的最低要求版本。对于每个所需的模块版本,该go命令加载该 go.mod版本的文件并合并该文件中的要求。
			加载所有需求后,该go命令使用最小版本选择 (MVS)解决它们以生成构建列表。
		replace, 
			指令将replace模块的特定版本或模块的所有版本的内容替换为其他地方的内容。可以使用另一个模块路径和版本或特定于平台的文件路径来指定替换。
		exclude, 
			该指令 阻止go命令加载模块版本
			在go >1.16 如果任何文件中的指令引用的版本被主模块文件中go.mod 的指令排除,则忽略该要求。这可能会导致类似 和添加对更高版本的新要求的命令,并在适当的情况下添加注释。excludego.modgo getgo mod tidygo.mod// indirect
			//如 排除
			exclude golang.org/x/net v1.2.3

			exclude (
			    golang.org/x/crypto v1.4.5
			    golang.org/x/text v1.6.7
			)

		retract。
			指令指示不应依赖于定义的模块 retract 版本或版本范围。
			go.mod 当版本过早发布 或版本发布后 问题严重时,指令很有用。
			收回的版本应该在版本控制存储库和模块代理 保持可用。
			考虑模块作者意外example.com/m 发布版本的情况。v1.0.0为了防止用户升级到 v1.0.0,作者可以在 中添加两个retract指令,然后用撤消go.mod标记 。v1.0.1
			// 回收 撤回
			retract (
			    v1.0.0 // Published accidentally.
			    v1.0.1 // Contains retractions only.
			)
			当 用户执行 go get example.com/m@latest时,该go命令会从 中读取撤消v1.0.1,这是现在的最高版本。v1.0.0和 都v1.0.1被收回,因此该go命令将升级(或降级!)到下一个最高版本,也许是v0.9.5.
                            
  • sum

     go.sum 
     一个模块可能在它的文件go.sum旁边有一个在它的根目录中命名的文本go.mod文件。
     该go.sum文件包含模块直接和间接依赖项的加密哈希。
     当go命令将模块.mod或.zip文件下载到模块缓存go.sum中时,它会计算一个哈希值并检查该哈希值是否与主模块文件中的相应哈希值匹配。
     go.sum如果模块没有依赖项,或者所有依赖项都使用 replace指令替换为本地目录,
     则可能为空或不存在校验和数据库是go.sum行的全局来源。
     该go命令可以在许多情况下使用它来检测代理或原始服务器的不当行为
    
     校验和数据库允许所有公开可用的模块版本的全局一致性和可靠性。
     它使不受信任的代理成为可能,因为它们无法提供错误的代码而不会被忽视。
     它还确保与特定版本相关联的位不会从一天到另一天发生变化,即使模块的作者随后更改了其存储库中的标签。
    
     校验和数据库由谷歌运行的sum.golang.org提供服务。
     它是由Trillian支持的行哈希的透明日志(或“Merkle 树”)。
     Merkle 树的主要优点是独立审计员可以验证它没有被篡改,因此它比简单的数据库更值得信赖。
    

    自动更新 go version >1.16

    go.mod如果缺少信息或不能准确反映现实,大多数命令都会报告错误。

     和命令go get可 go mod tidy用于解决大多数此类问题。
             
     此外,该-mod=mod标志可与大多数模块感知命​​令(go build、、go test等)一起使用,
             
     以指示命令自动go修复问题。go.mod go.sum
     更新go.mod以规范格式重新格式化,以便未来的机械更改将导致最小的差异。如果只需要格式更改,该go命令将不会更新。go.mod
    
     因为模块图定义了 import 语句的含义,任何加载包的命令也使用go.mod并因此可以更新它,包括 go build, go get, go install, go list, go test, go mod tidy。
    

2.3 第三方包管理 go get 安装包

这些包是 Go 项目的一部分,但在 Go 主树之外。

它们是在比 Go 核心更宽松的兼容性要求下开发的。使用“go get”安装它们。

比如在你的go模块中执行 go get pkg.go.dev/golang.org/…

benchmarks — 衡量 Go 开发的基准。
blog — blog.golang.org 的实现。
build — build.golang.org 的实现。
crypto — 额外的加密包。
debug — Go 的实验性调试器。
image — 额外的成像包。
mobile——在移动平台上对 Go 的实验性支持。
net — 额外的网络包。
perf — 用于性能测量、存储和分析的包和工具。
pkgsite — pkg.go.dev 网站的主页。
review — 一个处理 Gerrit 代码审查的工具。
sync ——额外的并发原语。
sys — 用于进行系统调用的包。
text — 处理文本的包。
time — 额外的时间包。
tools ——godoc、goimports、gorename 和其他工具。
tour - tour.golang.org 的实现。
exp — 实验性和不推荐使用的包(小心处理;可能会在没有警告的情况下更改)。

安装一个包

    go install golang.org/dl/go1.18beta1@latest

更新一个包

    go1.18beta1 download

给包取一个 别名

    alias goBeta1=go1.18beta1
    

查看版本

    goBeta1 version