【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关键字:用于将一个模块版本替换为另外一个模块版本。

相关推荐
东木月16 小时前
使用python获取Windows产品标签
开发语言·windows·python
该用户已不存在16 小时前
不止是初始化,4个C# 构造函数解析与实例
后端·c#·.net
pumpkin8451416 小时前
Go 基础语法全景
开发语言·后端·golang
踏浪无痕16 小时前
Go 的协程是线程吗?别被"轻量级线程"骗了
后端·面试·go
hqwest16 小时前
码上通QT实战18--监控页面10-获取设备数据
开发语言·qt·湿度·modbus功能码·寄存器地址·从站数据·0103
AIFQuant16 小时前
2026 越南证券交易所(VN30, HOSE)API 接口指南
大数据·后端·python·金融·restful
星火开发设计17 小时前
C++ multiset 全面解析与实战指南
开发语言·数据结构·c++·学习·set·知识
rannn_11117 小时前
【Java项目】中北大学Java+数据库课设|校园食堂智能推荐与反馈系统
java·数据库·后端·课程设计·中北大学
崔庆才丨静觅17 小时前
Veo API:0 门槛量产商业级视频!2026 视频流量密码,创作者/商家必藏
后端·google·api
野犬寒鸦17 小时前
从零起步学习MySQL || 第十六章:MySQL 分库分表的考量策略
java·服务器·数据库·后端·mysql