【go语言 | 第6篇】Go Modules 依赖解决

文章目录

Go Modules是什么?

Go Modules 是 Go 语言的依赖解决方案

Go Modules 目前集成在 Go 的工具链中,只要安装了 Go,自然就可以使用 Go modules,Go modules 解决了 Go1.11 前的几个常见问题:

(1)Go 语言长久以来的依赖管理问题。

(2)"淘汰"现有的 GOPATH 的使用模式

(3)统一社区中的其它的依赖管理工具(提供迁移功能)

GOPATH 的工作模式

GOPATH下有三个文件夹:

bin :代表已经编译过的 go 语言的所有可执行程序。
pkg :存储默认文件,加快编译速度。
src:所有的源文件。

GOPATH 的弊端

(1)无版本控制概念。无法知道当前拉取的是哪个版本,也无法指定拉取自己的期望版本。

(2)无法同步一致第三方版本号。无法保证自己的版本与其他人的版本一致。

(3)无法指定当前项目引用的第三方版本号。

Go Modules模式

go mod命令

通过:go mod help

可以查看go mod命令

命令 作用
go mod init 生成go.mod文件
go mod download 下载go.mod 文件中指明的所有依赖
go mod tidy 整理现有的依赖
go mod graph 查看现有的依赖结构
go mod edit 编辑 go.mod 文件
go mod vendor 导出项目所有的依赖到vendor目录
go mod verify 校验一个模块是否被篡改过
go mod why 查看为什么需要依赖某模块

go mod环境变量

通过 go env 命令查看环境变量:

(1)GO111MODULE

Go语言提供了GO111MODULE这个环境变量来作为Gomodules的开关,其允许设置以下参数:

  • auto:只要项目包含了go.mod文件的话启期Go modules,目前在Go1.11至Go1.14中仍然是默认值。
  • on:启用Gomodules,推荐设置,将会是未来版本中的默认值。
  • off:禁用Go modules,不推荐设置。

可以通过来设置:go env -w G0111MODULE=on

(2)GOPROXY

这个环境变量主要是用于设置Go模块代理(Gomoduleproxy),其作用是用于使Go在后续拉取模块版本时直接通过镜像站点来快速拉取

GOPROXY 的默认值是:https://proxy.golang.org,direct

proxy·golang.org国内访问不了,需要设置国内的代理。

  • 阿里云:https://mirrors.aliyun.com/goproxy/
  • 七牛云:https://goproxy.cn,direct

direct:用于指示Go回源到模块版本的源地址去抓取(比如GitHub等)

(3)GOSUMDB

它的值是一个Go checksum database,用于在拉取模块版本时(无论是从源站拉取还是通过Gomodule proxy拉取)保证拉取到的模块版本数据未经过篡改,若发现不一致,也就是可能存在篡改,将会立即中止。

GOSUMDB 的默认值为:sum.golang.org,在国内也是无法访问的,但是GOSUMDB 可以被Go模块代理所代理。

因此我们可以通过设置GOPROXY来解决而先前我们所设置的模块代理goproxy.cn就能支持代理sum.golang.org,所以这一个问题在设置GOPROXY后,你可以不需要过度关心。

(4)GONOPROXY、GONOSUMDB、GOPRIVATE

Go Modules初始化项目

  1. 开启Go Modules
cmd 复制代码
go env -w GO111MODULE=on
  1. 初始化项目
    创建项目目录:在 E 盘下的 go_modules 文件夹下创建项目目录为 modules_test。
    执行 Go modules 初始化,起一个当前项目的模块名称:go init github.com/go_modules/modules_test

    初始化完成后,生成了 go.mod 文件:

    打开 go.mod 文件:
  2. 在项目目录下编写源代码,创建 main.go 文件
go 复制代码
package main

import (
    "fmt"
    "github.com/aceld/zinx/znet"
    "github.com/aceld/zinx/ziface"
)

//ping test 自定义路由
type PingRouter struct {
    znet.BaseRouter
}

//Ping Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
    //先读取客户端的数据
    fmt.Println("recv from client : msgId=", request.GetMsgID(), 
              ", data=", string(request.GetData()))

    //再回写ping...ping...ping
    err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))
    if err != nil {
      fmt.Println(err)
    }
}

func main() {
    //1 创建一个server句柄
    s := znet.NewServer()

    //2 配置路由
    s.AddRouter(0, &PingRouter{})

    //3 开启服务
    s.Serve()
}

当前的 go_modules/modules_test 项目,依赖一个叫github.com/aceld/zinx库的,znet和ziface只是zinx的两个模块。

在 go_modules/modules_test 下执行:go get github.com/aceld/zinx/znet

此时 go.mod 文件被修改,并生成了 go.sum 文件:

(1)go.mod 文件:

  • module:用于定义当前项目的模块路径
  • go:标识当前Go版本
  • require:当前项目依赖的一个特定的必须版本
    // indirect:表示该模块为间接依赖。项目直接依赖的是 znet 包,间接依赖 zinx 包。

(2)go.sum 文件

go.sum 文件详细罗列了当前项目直接或间接依赖的所有模块版本 ,并写明了模块版本的 SHA-256 哈希值以备 Go 在今后的操作中保证项目所依赖的那些模块版本不会被篡改

一个模块路径可能有如下两种:

  • h1:hash情况:是 Go modules 将目标模块版本的 zip 文件开包后,针对所有包内文件依次进行 hash,然后再把它们的 hash 结果按照固定格式和算法组成总的 hash 值。

  • go.mod hash情况:对 go.mod 文件做的hash

h1 hash 和 go.mod hash 两者,要不就是同时存在,要不就是只存在 go.mod hash。当 Go 认为肯定用不到某个模块版本的时候就会省略它的 h1 hash,就会出现不存在 h1 hash,只存在 go.mod hash 的情况。

修改模块的版本依赖关系

当前依赖的zinx版本是最新版本:

如果想要使用以前的旧版本,可以通过在项目目录下执行:

cmd 复制代码
go mod edit -replace=zinx@v1.2.7=zinx@v0.0.0-20200221135252-8a8954e75100

此时,go mod文件:

replace关键字:用于将一个模块版本替换为另外一个模块版本。

相关推荐
小oo呆2 小时前
【学习心得】Python的TypedDict(简介)
开发语言·python
文洪涛2 小时前
VS Code Python “第一次运行失败 / 先执行 python 再激活 Conda” 问题定位与解决
开发语言·python·conda
weixin_425023002 小时前
Spring boot 2.7.18使用knife4j
java·spring boot·后端
IT_陈寒2 小时前
Python性能翻倍的5个隐藏技巧:让你的代码跑得比同事快50%
前端·人工智能·后端
wanghowie2 小时前
01.08 Java基础篇|设计模式深度解析
java·开发语言·设计模式
wjs20242 小时前
Memcached stats 命令详解
开发语言
云技纵横3 小时前
Stream API 从入门到实践:常用操作、易错点与性能建议
开发语言·windows·python
Knight_AL3 小时前
Java 17 新特性深度解析:记录类、密封类、模式匹配与增强的 switch 表达式对比 Java 8
java·开发语言