Go语言中的包管理工具之Go Modules的使用

GoLang 中常用的包管理的方式

  • 常用的有三种
    • Go Path
    • Go Vendor
    • Go 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.10
Go Vendor >= 1.5 版本2015.8.19
Go 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 GO111MODULE=on
  • 在Windows环境
    • 我们可以通过 set命令将 GO111MODULE 设置成 on
      • $ set GO111MODULE=on
    • 当然直接修改 Go 的 Path 环境变量也是可以的
  • 还有一种方式是两种类型的操作系统都可以支持的
    • 我们可以通过 $ go env -w GO111MODULE=on
    • 加上 -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 Proxy
      • GOPROXY 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 GOPROXY=https://goproxy.cn/,https://mirrors.aliyun.com/goproxy/,direct
    • 也支持 $ go env -w GOPROXY=https://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.go
    package mainimport 'github.com/astaxie/beego/logs'func 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 GOSUMDB=off
    • 或 将环境变量添加到 /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名保持一致,这样也能方便我们对项目进行管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python学习 21 excel分列

简单做了个模板&#xff0c;能干这个&#xff1a; 指定sheet中某列数据进行按需拆分&#xff0c;拆分后新建一个test的sheet&#xff0c;将数据分别存入test的不同列中。 import os import xlwings as xw import re #excel路径 pathrC:\Users\xxx\Desktop\123.xlsx#设置需要…

【代码随想录】刷题笔记Day42

前言 这两天机器狗终于搞定了&#xff0c;一个控制ROS大佬&#xff0c;一个计院编程大佬&#xff0c;竟然真把创新点这个弄出来了&#xff0c;牛牛牛牛&#xff08;菜鸡我只能负责在旁边喊加油&#xff09;。下午翘了自辩课来刷题&#xff0c;这次应该是元旦前最后一刷了&…

行车记录仪变清晰,变高清的办法一定要收藏

有时候我们会发现行车记录仪拍摄的视频不够清晰&#xff0c;特别是出现事故需要视频为证的时候&#xff0c;如果视频太模糊&#xff0c;很难获得交警的支持&#xff0c;那么如何让行车记录仪拍摄的视频变得更加清晰呢&#xff1f; 小编给大家分享几个办法&#xff0c;建议收藏…

Android实验:contentprovider 实验+SQLite 数据库的实现

目录 SQLite实验目的实验内容实验要求项目结构代码实现结果展示 SQLite SQLite 是一个开源的嵌入式关系数据库&#xff0c;实现了自给自足的、无服务器的、配置无需的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库系统不同&#xff0c;…

全面好用的setting.xml配置

<?xml version"1.0" encoding"UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information…

轻松实现iphone截图传电脑

目录 摘要 引言 用户登录工具和连接设备 生成截图 摘要 本篇博文介绍了克魔助手这款工具&#xff0c;解决了iPhone与Windows系统下图片传输的烦恼。通过连接同一Wi-Fi&#xff0c;使用克魔助手轻松实现了iPhone截图传输到电脑上的便捷操作。用户只需简单地下载并安装克魔助…

前端优化 - 防抖和节流

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

使用Go-Gin框架实现 OSS 前端直传功能

引言 在现代 Web 应用中&#xff0c;文件上传是一项常见功能。传统的上传方式通常需要文件经过后端服务器转发到对象存储服务&#xff08;如阿里云 OSS&#xff09;。然而&#xff0c;这种方法可能对服务器造成额外的负担&#xff0c;并降低上传效率。本文将探讨如何使用 Go-G…

Harmony全局应用生命周期 EntryAbility.ts 讲解

之前 我们说过 page页面的生命周期 组件的生命周期 其实他和uni一样有一个整个应用的生命周期 我们如下图打开EntryAbility.ts 这是我们整个程序app的状态控制 他这里也有几个全局的生命周期 比如 我们手机 点开当前 App 启动 app 会触发 它的 onCreate 生命周期 当我们从手…

Elasticsearch 8.X进阶搜索之“图搜图”实战

Elasticsearch 8.X “图搜图”实战 1、什么是图搜图&#xff1f; "图搜图"指的是通过图像搜索的一种方法&#xff0c;用户可以通过上传一张图片&#xff0c;搜索引擎会返回类似或者相关的图片结果。这种搜索方式不需要用户输入文字&#xff0c;而是通过比较图片的视…

米贸搜|LinkedIn和Facebook在营销上有哪些区别?

一、领英做营销有哪些优势&#xff1f; 领英为什么受到很多营销人员的欢迎呢?因为领英的功能和大多数的社交平台都有所不同&#xff0c;自然在做营销这一方面也有其他平台所不能达到的优势&#xff0c;在这里也为大家总结了几点&#xff1a; 1、领英是一个专业的职场社交平台…

前端八股文(工程化篇)

目录 1.常用的git命令有哪些&#xff1f; 2.git rebase和git merge的区别 3.有哪些常见的Loader和Plugin&#xff1f; 4.webpack的构建流程 5.bundle,chunk,module是什么&#xff1f; 6.如何提高webpack的打包速度 7.vite比webpack快在哪里 8.说一下你对Monorepo的理解 …

MySQL MVCC精讲

版本链 我们前面说过&#xff0c;对于使用InnoDB存储引擎的表来说&#xff0c;它的聚簇索引记录中都包含两个必要的隐藏列&#xff08;row_id并不是必要的&#xff0c;我们创建的表中有主键或者非NULL的UNIQUE键时都不会包含row_id列&#xff09;&#xff1a; trx_id&#xff…

GBASE南大通用-GBase 8s分片表操作 提升大数据处理性能

目录 一、GBase 8s分片表的优势 二、六种分片方法 轮转 1.轮转法 基于表达式分片 2.基本表达式 3.Mod运算表达式 4.Remainder关键字方式 5.List方式 6.interval 固定间隔 三、分片表的索引 1.创建索引的注意事项 2.detach索引替代delete功能展现 3.在现有分片表上增加一个新…

状态模式-概述

在软件系统中&#xff0c;有些对象也像水一样具有多种状态&#xff0c;这些状态在某些情况下能够相互转换&#xff0c; 而且对象在不同的状态下也将具有不同的行为。相同的方法在不同的状态中可能会有不同的实现。 为了实现不同状态下对象的各种行为以及对象状态之间的相互转换…

【Apache Doris】自定义函数之 JAVA UDF 详解

【Apache Doris】自定义函数之 JAVA UDF 详解 一、背景说明二、原理简介三、环境信息3.1 硬件信息3.2 软件信息 四、IDE准备五、JAVA UDF开发流程5.1 源码准备5.1.1 pom.xml5.1.2 JAVA代码 5.2 mvn打包5.2.1 clean5.2.2 package 5.3 函数使用5.3.1 upload5.3.2 使用 六、注意事…

2023年03月18日_微软office365 copilot相关介绍

文章目录 Copilot In WordCopilot In PowerpointCopilot In ExcelCopilot In OutlookCopilot In TeamsBusiness Chat1 - copilot in word2 - copilot in excel3 - copilot in powerpoint4 - copilot in outlook5 - copilot in teams6 - business chat word 1、起草草稿 2、自动…

JavaScript使用教程(二):类型、值和变量

计算机程序通过操作值&#xff08;如数值3.14&#xff09;或文本&#xff08;如“Hello World”&#xff09;来工作。编程语言中这些可以表示和操作的值被称为类型&#xff0c;而一门语言支持的类型集也是这门语言最基本的特征。程序在需要把某个值保存下来以便将来使用时&…

腾讯云系统盘50G通用型SSD云硬盘不够用怎么办?

腾讯云服务器系统盘50G通用型SSD云硬盘不够用怎么办&#xff1f;可以云硬盘扩容&#xff0c;也可以挂载数据盘。腾讯云服务器的系统盘可以不停服在线扩容&#xff0c;数据存储也可以通过挂载数据盘来实现更大的容量空间。腾讯云百科txybk.com分享腾讯云服务器系统盘不够用的操作…

2023 年终总结

引言 先说 2022 年留下的期待完成情况 健身&#xff0c;经过教练的指导后&#xff0c;自己开始做计划锻炼了&#xff0c;逐渐掌握到健身的要领&#xff1a;脸皮厚。 读书&#xff1a;今年可以说是读书最多的一年了&#xff0c;书单很长 旅行&#xff1a;去了上海&#xff0c;哈…