如何快速网站备案,网站编程设计方向,手机网站广告代码,海口网约车平台有哪些GoLang 中常用的包管理的方式
常用的有三种 Go PathGo VendorGo Modules
关于 Go Modules 1 ) 概述
Go的包管理#xff0c;经过社区和官方的共同努力下#xff0c;最终在百家争鸣后Go官方在 2018.8 推出了go 1.11版本中的Go Modules#xff0c;并且很快成为一统江湖的包…GoLang 中常用的包管理的方式
常用的有三种 Go PathGo VendorGo Modules
关于 Go Modules 1 ) 概述
Go的包管理经过社区和官方的共同努力下最终在百家争鸣后Go官方在 2018.8 推出了go 1.11版本中的Go Modules并且很快成为一统江湖的包管理方式Go Modules已经成为目前最主流的包管理工具需要注意的是go从1.13版本开始 Go Modules 被默认选择使用在go的1.11 和 go的1.12 版本中需要我们手动开启 Go Modules
管理方式版本发布时间GoPath 模式 1.5 版本2009.11.10Go Vendor 1.5 版本2015.8.19Go Modules 1.11 版本 2018.8.24
关于Go Modules我们必须要搞明白下面这几个问题 第一个是 Go Modules 的用法第二个是 go.mod 文件是什么时候生成的有什么作用具体有哪些内容go.sum 文件是什么时候生成的有什么作用具体有哪些内容其中的哈希值是怎么计算的, 怎么实现包校验的
2 ) Go Modules 用法
在go1.11的时候就发布了 Go Modules, 但是功能默认是关闭的直到go的1.13版本才开始开启所以在go 1.11 和 go 1.12 版本中我们需要通过go提供的变量GO111MODULE 来开启 Go Modules 这里跟之前的 Go Vendor 里面开启 govendor 的环境变量即GO15VENDOREXPERIMENT 这个环境变量类似 GO111MODULE 也属于go的阶段性变量 通常在某个功能发布之初的几个版本是需要手动去开启的等稳定下来被开发者接受之后会在后续的版本中默认开启 GO111MODULE它有三个值 第一个是 on, 它表示开启 Go Modules第二个是 off 它表示关闭 Go Modules第三个是 auto 当项目路径在Go Path目录外部时 如果你设置的是 auto 的话我们这个 GO111MODULE 就会被设置成 on 那当项目路径在 Go Path内部时 即使存在 go.mod 文件, 也会将 GO111MODULE 设置成 off 在Unix环境下(Linux, MacOS) 需要把 GO111MODULE 设置成 on然后通过 export 将这个环境变量导出export GO111MODULEon 在Windows环境 我们可以通过 set命令将 GO111MODULE 设置成 on $ set GO111MODULEon 当然直接修改 Go 的 Path 环境变量也是可以的 还有一种方式是两种类型的操作系统都可以支持的 我们可以通过 $ go env -w GO111MODULEon加上 -w 参数来将这个 GO111MODULE 设置成on如果没有任何输出就是正常了注意我们在执行上面这个命令的时候可能会抛出一个 warning这个waring的意思, 就是说我们不能通过这个 go env 指令去覆盖我们环境变量的设置也就是说如果我们在环境变量里面已经设置了 GO111MODULE 这个环境变量我们就需要去改环境变量里面这个 GO111MODULE 这个值而不能通过命令的方式去设置通常这些环境变量可能会在 /etc/profile 文件里或者是 ~/bash.profile文件里或者是 /etc/.bashrc 文件里或者是 ~/.bashrc 文件里或者是 ~/.profile 文件里 需要注意的是仅仅设置 GO111MODULE这个环境变量为on并不能代表项目就使用了 Go Modules 方式来管理包 我们使用 $ go mod init 将项目初始化成一个 Go Modules 工程这个命令需要在项目的根目录下执行执行成功后在当前目录下面生成一个 go.mod 的文件
3 ) go mod 的具体用法
需要准备好环境go版本 需要 1.11 如果go的版本没有到 1.13, 就需要将 GO111MODULE 设置成 on查看我们当前使用的go版本通过 $ go version 之后可能需要设置go代理 如果我们是开发环境我们可以直接在这个编辑器IDE上进行设置比如 GoLand在这个编辑器上file / settings里面就可以对这个go的环境变量进行配置可以找到Go Modules 需要勾选这个 Enable Go modules integration填入 Environment, 设置 Go Path 和 Go ProxyGOPROXY https://goproxy.cn/,https://mirrors.aliyun.com/goproxy/,direct这里 direct的意思是当从上面两个途径无法获取就从源码获取GOPRIVATE 这个变量是内部包的配置一般在公司部署的私网内的地址 在生产环境中的设置 比如在Unix环境下 我们可以通过将下面export GOPROXY https://goproxy.cn/,https://mirrors.aliyun.com/goproxy/,direct放入 /etc/profile 里面 在Windows下通过 set 指令设置 GOPROXY $ set GOPROXYhttps://goproxy.cn/,https://mirrors.aliyun.com/goproxy/,direct 也支持 $ go env -w GOPROXYhttps://goproxy.cn/,https://mirrors.aliyun.com/goproxy/,direct
4 ) 工程示例
$ mkdir go-mod-test cd go-mod-test 目录, 仅作为示例$ go mod init go-mod 创建一个go-mod工程目录可看到里面生成一个 go.mod 文件在这里就可以编写程序了$ touch main.gopackage mainimport github.com/astaxie/beego/logsfunc main() {logs.Warn(demo)
}现在解决 第三方包 引用的问题, 到工程根目录中执行$ go mod tidy 这时候就会自动找到项目以来的包解决工程中包依赖的关系如果缺少包则下载并维护信息到 go.mod如果没有用的则移除 执行 go run main.go 正常输出在 go.mod 下又生成了 go.sum的文件 这里写的是工程所有直接依赖包和间接依赖包 go mod download 下载依赖包到本地缓存如果 go.mod 和 go.sum 已经包含依赖包的信息而且依赖包还没有下载到本地这个指令会把依赖包下载到本地 go mod vendor 为了兼容 go vendor 模式在 go mod 发布之前go vender 使用是比较普遍的go mod 也支持将依赖包通过我们这个go mod vender 指令复制到我们项目 vendor 目录当中可以看到我们当前这个项目里面是没有 vendor 目录的那我们在这个项目的根目录里面执行 go mod vendor 刷新一下我们可以看到它就为我们生成的一个vendor目录在 vendor 里面还有一个 modules.txt 文件这个文件记录了我们当前这个venders里面依赖的包以及包的版本信息。 那上面四个指令是最常用的还有一些其他指令 比如 $ go help mod 可以看到我们go mod支持的一些指令这里面包括还有一些 go mod graphgo mod why, 以及 go mod verify这些是查看和校验依赖的一些指令go mod edit, 我们可以用来编辑这个 go.mod 文件, 平时也很少使用 我们了解即可
5 ) 关于 go.mod 和 go.sum
接下来需要重点了解两个文件 1 ) go.mod 这个文件里面主要是描述了模块的一些属性包括它的其他模块的go版本的依赖的信息 里面第一行就是 module 的name这个name一般使用 git仓库上的路径第二行是版本信息项目依赖的最低版本要求只是获取当前go版本的信息第三行require 指令包含导入的 非工程项目内的包后面都是 require工程依赖包有直接依赖包如beego, 还有间接依赖包 所谓间接依赖包就是直接依赖包的依赖包如果beego中需要依赖一些包有一些包没有 go.mod 文件则会添加到工程的 go.mod中并且生成一个尾版本号 尾版本号格式: 版本号 - UTC的提交时间(提交到github的时间) - commit 哈希的前缀 2 ) go.sum 在触发项目编译后生成如 go buildgo run等指令里面详细罗列了项目直接或间接依赖的所有模块的版本每一条包含了模块依赖的路径导入的版本和哈希值每个依赖包有可能有多条信息 一种是有 go mod 标识后面哈希值是 go.mod 的哈希另一种没有则后面的哈希是包的每一个文件的哈希 实现包的校验 当我们拿到某个项目的源代码并尝试在构地进行构建的时候go命令会从本地缓存中去查找所有 go.mod 中记录的依赖包并且会计算出本地依赖包的哈希值然后与我们 go.sum 文件中的记录进行对比, 也就是说它会检测某地缓存中使用的依赖包的版本是否满足项目中 go.sum 文件中期望的版本如果不满足就说明本地缓存目录当中的依赖包版本和项目中go.sum文件记录的版本的哈希值是不一致的这个时候构建就会被拒绝。这样就可以确保相同的依赖包在任何环境使用这些依赖包的源码它都是一样的依赖包中任何一个文件包括 go.mod 的改动都会改变它整体的哈希值在 go.sum 中记录额外的 go.mod 的文件就是为了在计算这个依赖树的时候不用去下载完整的依赖包版本只根据 go.mod 就可以计算出这个依赖信息主要目的就是加快这个依赖包的校验那每条记录的哈希值, 都有一个表示的哈希算法的一个h1的哈希算法。这个哈希算法是由SHA-256计算出来的那模块版本的SHA-256的哈希值主要是用来校验当前缓存的模块用来准备go在今后的操作过程中保证项目中所有的依赖的那些模块版本都不会被篡改在每次我们构建项目发现有模块缺少的时候如果在缓存中不存在那就需要下载并且计算这个包的哈希并且添加到 go.sum当中如果缓存中已经存在就需要匹配 go.sum 中已有的记录需要注意的是在每次缺少模块的时候也就是说我们需要的依赖包它不在 go.sum 文件当中而且是一个公网可下载的包go命令就会去go的校验数据库获取模块的校验和它的默认配置是这个 sum.golang.org我们也可以使用中国大陆官方的这个校验数据库 sum.golang.google.cn这个校验数据库会查询并获取这个模块的校验和如果下载的这个模块的校验和与它计算出来的校验和不匹配那我们的 go mod 命令就没办法成功执行, 那如果能够匹配就会把校验和写到go.sum文件当中这里有三种情况它不会对依赖包做哈希校验 第一种, 就是我们配置的这个 GOPRIVATE 匹配到的包 当我们配置的 GO PRIVATE 这个环境变量被我们 GO PRIVATE 匹配到的这些模块包就不会check sum校验GO PRIVATE 这个变量主要是用来设置我们内部的一些包, 不走 GO PROXY 配置的代理因为内部的包基于代码安全的考虑都不会上传到我们的github上面 第二个, 就是我们可以通过 go mod vendor 命令将依赖包全部下载到我们工程的根目录下的 vendor 目录下面 它可以用来做离线编译打包到 vendor 目录中的包也不会再做哈希校验 第三个, 就是 GOSUMDB 设置为off的时候 所有的包都不会做包校验相当于关闭了我们这个go sum的校验 需要注意的是同一个模块版本的数据只会缓存一份。那所有其他模块呢都会共享使用。 如果你希望清除当前已经缓存的模块的版本数据可以执行这个 $ go clean -modcache
6 ) go.mod 和 go.sum 对比
为什么我们看到的 go.sum 文件中记录的依赖包的版本数量会比go.mod 文件要多很多go.mod 记录的是直接依赖的依赖包版本直接依赖包版本不含 go.mod 文件时才记录构建依赖赖的版本go.sum则是要记录构建依赖到的所有依赖包的版本它包括直接依赖包和间接依赖包
7 关闭依赖包校验
如果不希望进行依赖包校验可以关闭可以将这个GOSUMDB 设置成 off 就可以关闭我们当前的 go sum 校验 $ go env -w GOSUMDBoff或 将环境变量添加到 /etc/profile
8 ) 依赖包的存储对比
Go Path 模式下和 Go Modules 模式下依赖包的存储路径是不一样的在 Go Path 模式下依赖包存储在这个 $GOPATH/src这个目录下只保存特定依赖包的一个版本我们通过 go get 下载的包也包含完整的仓库信息的也就是包含了 .git 的目录而我们在 GOMODULES 模式下依赖包会存储在这个 $GOPATH/pkg/mod 下面 而且这个目录下面可以存储特定依赖包的多个版本每个版本会占用一个目录那这个目录里面只包含依赖包文件不包含 .git 的目录
Go编码原则与建议
构建go项目的时候也需要遵循一些原则和规范性的建议1 ) 我们一个目录名下面只能有一个package否则我们的编译器就会报错2 ) 建议一个package名的内容放在一个目录下面, 方便我们做项目管理3 ) 建议目录名和package名保持一致这样也能方便我们对项目进行管理