go mod的使用方法小结

目录
  • 前言
  • 1.go modules的基本介绍
    • 1.1 提供的命令
    • 1.2 提供的环境变量
      • 1.2.1 说明
  • 2.go modules的基本使用
    • 2.1 初始化项目
  • 3.使用go mod发布自己的包
    • 3.1 发布公开的包
    • 3.2 发布私有包

前言

对于多个项目来说,把所有的源码都放在GOPATH下的src目录下非常的不方便。golang给我们提供了一个叫go mod的命令来脱离src目录,方便我们管理go项目。go mod 是go官方提供的go版本管理的一个方案,目前1.15已经可用于生产环境。

1.go modules的基本介绍

1.1 提供的命令

在go环境的shell中执行go mod help查看命令和说明。

Usage:

        go mod <command> [arguments]

The commands are:

        download    download modules to local cache
        edit        edit go.mod from tools or scripts
        graph       print module requirement graph
        init        initialize new module in current directory
        tidy        add missing and remove unused modules
        vendor      make vendored copy of dependencies
        verify      verify dependencies have expected content
        why         explain why packages or modules are needed

1.2 提供的环境变量

go env查看go的环境变量,在所有go提供的环境变量中,有一个是和go mod相关的。

GO111MODULE="on"
GOPROXY="https://goproxy.cn,direct"
GONOPROXY="git.example.com,x1"
GONOSUMDB="git.example.com,x1"
GOPATH="/home/go-project/"
GOPRIVATE="git.example.com,x1"
GOSUMDB="sum.golang.org"
# 省略其余环境变量...

1.2.1 说明

1) GO111MODULE

go语言提供GO111MODULE环境变量三个值,用于GO111MODULE的开关:

  • auto:只要项目中包含了go.mod这个文件,就启动该项目的go modules,在 Go1.11 至 Go1.14 中仍然是默认值。
  • on:启动go modules
  • off:关闭go modules

2) GOPROXY

go env中默认的代理是GOPROXY="https://proxy.golang.org,direct",但是在国内是无法访问的,这里需要设置成国内的代理地址GOPROXY="https://goproxy.cn,direct"

GOPROXY的值是一个以英文逗号 “,” 分割的 Go 模块代理列表,允许设置多个模块代理,假设你不想使用,也可以将其设置为 “off” ,这将会禁止 Go 在后续操作中使用任何 Go 模块代理。

direct

实际上 “direct” 是一个特殊指示符,用于指示 Go 回源到模块版本的源地址去抓取(比如 GitHub 等),场景如下:当值列表中上一个 Go 模块代理返回 404 或 410 错误时,Go 自动尝试列表中的下一个,遇见 “direct” 时回源,也就是回到源地址去抓取,而遇见 EOF 时终止并抛出类似 “invalid version: unknown revision…” 的错误。

在cmd中执行set GO111MODULE=on

3)GONOPROXY/GONOSUMDB/GOPRIVATE

这三个环境变量都是用在当前项目依赖了私有模块,例如像是你公司的私有 git 仓库,又或是 github 中的私有库,都是属于私有模块,都是要进行设置的,否则会拉取失败。对于一些自己的私有模块代码,需要在GOPRIVATE上设置,在拉取时会提示输入用户名和密码。

可以设置多个,用英文的逗号分隔开;或者用通配符等

go env -w GOPRIVATE="git.example.com,github.com/eddycjy/mquote"
go env -w GOPRIVATE="*.example.com"	# 通配example.com的域名

2.go modules的基本使用

开启go modules后,就可以创建项目并且生成mod文件,来管理项目的所有依赖了。以下是go env环境的配置:

GO111MODULE="auto"
GOARCH="amd64"
GOBIN="/go/bin/"
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/go-project/"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build940953411=/tmp/go-build -gno-record-gcc-switches"

设置了GOPATH/home/go-project/,并且代理指向了国内的代理地址,防止国外镜像无法访问的情况。

2.1 初始化项目

$GOPATH目录下创建一个新的项目example.com/mycount/helloexample.com模拟github.com,mycount模拟账号,hello是最终的项目名称。目录和文件结构:

2.1.1 初始化.mod文件

hello目录下执行go mod init example.com/mycount/hello初始化hello项目的mod文件,如下:

执行完初始化操作后生成了一个go.mod的文件,里面只记录了2行:

  • module:用于定义当前项目的模块路径
  • go:用于标识当前模块的 Go 语言版本,值为初始化模块时的版本,目前来看还只是个标识作用

2.1.2 简单一个示例

hello目录下写一个main.go的文件,里面用了一个第三方的库。

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/json-iterator/go"
)

type resp struct {
	Status  int    `json:"status"`
	Message string `json:"message"`
}

func main() {
	router := gin.Default()
	router.GET("/", hello())
	if err := router.Run(":6060"); err != nil {
		panic(err)
	}
}

func hello() gin.HandlerFunc {
	return func(context *gin.Context) {
		strResp, _ := jsoniter.MarshalToString(resp{
			Status:  http.StatusOK,
			Message: "success",
		})
		context.String(http.StatusOK, strResp)
	}
}

hello目录下执行go get命令,拉取依赖库:

拉取依赖之后生成了一个go.mod和go.sum文件,go.mod文件:

go.sum的内容:

同时在$GOPATH目录下多了一个pkg文件,里面有拉取的文件依赖。这个文件是一个全局的缓存,

2.1.3 go modules的go get

在拉取项目依赖时,你会发现拉取的过程总共分为了三大步,分别是 finding(发现)、downloading(下载)以及 extracting(提取), 并且在拉取信息上一共分为了三段内容:

需要注意的是,所拉取版本的 commit 时间是以UTC时区为准,而并非本地时区,同时我们会发现我们 go get 命令所拉取到的版本是 v0.0.0,这是因为我们是直接执行 go get -u 获取的,并没有指定任何的版本信息,由 Go modules 自行按照内部规则进行选择。

那么我想选择具体版本应当如何执行呢,如下:

3.使用go mod发布自己的包

3.1 发布公开的包

公开的发布包无需修改go env中的一些环境变量,默认的环境变量即可

3.1.1 包的实现

假设我们有一个模块需要提供给第三方使用,并且这个包是发布在了gittee上,假设我在gitee上得账号是gitee.com\luciferofwg。我们后期会根据迭代或者功能维护版本,每当有更新或者升级的时候就发布最新的版本,版本遵循语义化版本定义。什么是语义化版本
这个包中包含一个函数,用于打印一句话,如下所示:

// hello.go
package hello

import "fmt"

func SayHello()  {
		fmt.Println("hello world")
}

在GOPATH下新建目录hello,在命令行下进入hello目录,执行go mod init来生成go mod文件,如下:

生成的包名为gitee.com/luciferofwg/hello,后期在引用这个包时就import 这个包名。
hello仓库提交到gitee上,完成发布包的第一个阶段。

3.1.2 包的发布

经过上一步骤,在仓库中就有了一个名为hello的公开仓库,如下:

假如我们认为这个版本是稳定可靠的,这时候我们需要发布一个可以使用的版本,gitee发布的流程如下:
点击仓库中右侧的创建按钮,在弹出的页面中创建发行版本号,填写完毕后点击创建发行版本完成发布。

图1 创建发行版本

图2 发行版本信息

图3 已创建的发行版本

到此我们发行了一个版本为v1.0.4的版本。

3.1.3 包的使用

对于已经发行的包,这里介绍如何使用它。首先定义一个名为test的包,因为test为调用的程序,因此我们初始化mod时直接按照程序的名字初始化,即:go mod test,完成初始化。如下:

test目录下编写如下代码:

package main
import "gitee.com/luciferofwg/hello"
func main()  {
	hello.SayHello()
}

然后再命令行中执行go mod tidy整理go mod,此时go mod会根据程序包的引用关系按照包名从互联网上拉去对应的包。执行完成后go.mod如下:

运行的结果:

需要注意的是:

默认拉去的是最新的发布版本,如果想制定版本,只需要修改go.mod中require最后面的版本号即可。如何修改go.mod参考go help mod命令的edit项。

3.2 发布私有包

3.2.1 go env环境变量和git配置的修改

1.go env环境变量的修改

私有包和公开包的区别最大的区别是权限的和git拉去包的过程,这时候需要对go env中的一些参数修改。涉及到的一些参数
GOINSECURE,GONOPROXY,GONOSUMDB,含义:
GOINSECURE:如果代码仓库是自己搭建的,没有“合法”的证书,则需要配置这个信息
GONOPROXY:在这个变量中配置的域名或者仓库地址不会走代理(我们在前面设置了cn的代理)
GONOSUMDB:1.15后会对包进行校验,此处的配置和GONOPROXY的含义一样
看一下我们的go env变量,之前已经修改过了,内容如下:

注:
windows下修改时直接将上述的配置增加系统的环境变量即可,linux下在bash的配置文件中修改(具体修改可以自行搜索)。

2.git配置的修改

由于是私有的包,拉去时需要获取拉去的权限,默认的https或者http的方式需要密码。如果我们本地已经配置了对应的gitee上的私钥,且已经在gitee对应的账户上配置了权限,那么我们就可以通过git@xxx的方式访问私有的仓库。
打开本地git的配置,windows下是c:\\user\\用户名\\.bashconfig文件,打开这个文件。增加以下代码:

[url "git@gitee.com:"]insteadof = https://gitee.com

表示访问https://gitee.com的过程替换为git@gitee.com:,即通过bash就可以访问私有库了。

3.2.2 私有包的实现

1.私有包实现

我们创建一个私有的仓库,名为hi,包含一个函数SayHello,打印hello world。
同样的,创建go.mod,实现SayHello函数,推送到gitee。

图1 私有仓库hi

2.函数和源码

// hi包的SayHello函数
package hi

import "fmt"

func SayHello() {
	fmt.Println("hi, world")
}

hi包的go.mod

3.2.3 私有包的发布

根据上述的源码,使用同样的方式发布版本。
图1 发布的版本1.0.0

3.2.4 私有包的引用

如果已经配置了go env的参数和git配置,使用的过程和公开包的使用是一样的。基于原来的版本,增加了一个hi包的函数引用和导入,在test目录下执行go mod tidy,就会自动拉取发布的包了。

package main

import (
	"gitee.com/luciferofwg/hello"
	"gitee.com/luciferofwg/hi"
)

func main() {
	hello.SayHello()
	hi.SayHello()
}

test程序的go.mod如下:

到此这篇关于go mod的使用方法小结的文章就介绍到这了,更多相关go mod使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • win10下go mod配置方式

    这是因为获取golang.org/x/...时需要翻墙,而我这里没有翻墙,不过没关系 设置下代理即可: // bash mac export GOPROXY=https://goproxy.io // powershell windows $env:GOPROXY = https://goproxy.io 然后再当前目录下 用powershell 执行命令: go mod download 相关命令: go mod init:初始化modules go mod download:下载module

  • go mod 安装依赖 unkown revision问题的解决方案

    背景 公司一个golang的项目,使用到了公司的私有仓库,去执行go mod tidy(下载依赖)的时候,到download公司私有库的时候就报错,报错信息也不明显,只是提示找不到影响版本unkown revision 小知识 go mod golang用来管理用来的,类似java的maven(但肯定没有maven这么好用) go mod tidy ,下载更新依赖 go install这种下载依赖的方式其实是通过go get的方式去下载的 go insall -x 加上-x命令,可以查看更多的错

  • goland使用go mod模式的步骤详解

    使用go mod之后,想要在goland中有代码提示,有两种方式,一种是使用gopath下的goimport工具,另一种是使用gomod自身的管理工具 我是用的是非gopath的方式,每次新建项目后总是报错 go list -m: can't compute 'all' using the vendor directory (Use -mod=mod or -mod=readonly to bypass.), 得不到想要的效果,最后终于发现是步骤不对 第一步:创建空文件夹 第二步:goland以

  • go mod 使用旧版本 版本号指定方式

    在使用go mod的过程中,发现不容易指定版本号 尤其是没有打tag的,不知道怎么指定版本号, 不知道有哪版本号 正常使用都没有问题,但是当引用的项目用了旧的代码, 这时候必须使用旧的版本,无法指定版本,不知道如何入手 尤其是k8s.io不知道是什么鬼, 从哪里看它的代码,只知道github.com 这个时候在 go.mod文件中 require 里面加上 github.com/kubernetes/cloud-provider 2bf8e45 此时会自动生成版本号, 其中 2bf8e45 这个

  • go自动下载所有的依赖包go module使用详解

    今天在学习dubbo-go的时候,下载了dubbo-go的example,依赖的包太多了,之前都是手动下载某个依赖的包,现在手动一个一个 go get 那太麻烦了.因为我是搞java的,刚开始用go的时候感觉有点奇怪,go代码所依赖的所有的第三方库都放在GOPATH这个目录下面,这就导致了同一个库只能保存一个版本的代码.如果不同的项目依赖同一个第三方的库的不同版本,应该怎么解决?总不能改包名吧,看了一下 dubbo-samples/golang/的代码 发现了有个 go.mod文件,百度一下 g

  • go mod 使用私有gitlab群组的解决方案

    由于go对私有gitlab的仓库支持不好,得使用下面这些步骤 设置git使用 ssh协议 git config --global url."git@gitlab.com:".insteadOf https://gitlab.com/ 添加ssh key 到gitlab ssh-keygen 会生成 id_rsa.pub cat ~/.ssh/id_rsa.pub 粘贴到gitlab 右上角头像 Setting -> SSH keys,或者打开链接https://gitlab.co

  • Goland使用Go Modules创建/管理项目的操作

    创建项目 Location:新项目文件夹GOROOT:go 安装根目录Proxy:https://goproxy.io,direct 重要:https://goproxy.io是下载go包的代理地址,设置后可在国内正常下载go仓库/github的包. 创建一个go文件 创建了一个test.go 下载安装需要的包 这里演示安装mysql driver包:github.com/go-sql-driver/mysql 直接import显示找不到包,使用左下方命令行工具,安装mysql driver 使

  • go mod的使用方法小结

    目录 前言 1.go modules的基本介绍 1.1 提供的命令 1.2 提供的环境变量 1.2.1 说明 2.go modules的基本使用 2.1 初始化项目 3.使用go mod发布自己的包 3.1 发布公开的包 3.2 发布私有包 前言 对于多个项目来说,把所有的源码都放在GOPATH下的src目录下非常的不方便.golang给我们提供了一个叫go mod的命令来脱离src目录,方便我们管理go项目.go mod 是go官方提供的go版本管理的一个方案,目前1.15已经可用于生产环境.

  • js中less常用的方法小结

    1.color 解析颜色 把代表颜色的字符串转换为颜色值 @c:'#000' .box{ background:color(@c) } 2.data-uri 把我们需要使用的素材图片转化成BASE64编码 ,项目中尤其是移动端的项目,节省了图片的加载时间,是图片优化的一个手段:LESS对于大图片是不能转码的,我们可以使用BASE64工具转码(tool.css-js.com) 项目中慎用,当你在移动端项目中有一些大图实在没有办法处理了的情况下在使用BASE64. @c:'#000' @url:'.

  • 快速解决Hash碰撞冲突的方法小结

    Hash碰撞冲突 我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突.如下将介绍如何处理冲突,当然其前提是一致性hash. 1.开放地址法 开放地执法有一个公式:Hi=(H(key)+di) MOD m i=1,2,-,k(k<=m-1) 其中,m为哈希表的表长.di 是产生冲突的时候的增量序列.如果di值可能为1,2,3,-m-1,称线性探测再散列. 如果d

  • python字符类型的一些方法小结

    int 数字类型 class int(object): """ int(x=0) -> int or long int(x, base=10) -> int or long Convert a number or string to an integer, or return 0 if no arguments are given. If x is floating point, the conversion truncates towards zero. If

  • js在ie下打开对话窗口的方法小结

    对话框的性质分为模态对话框和非模态对话框: 1.模态对话框: 打开该对话框之后,在该对话框之外的一切操作都是被禁止的,要想进行其他操作,必须先关闭本对话框. js命令: showModalDialog(); 2.非模态对话框: 和模态对话框相反,打开之后,仍可以进行对话框之外的操作. js命令: showModelessDialog(); 以上就是小编为大家带来的js在ie下打开对话窗口的方法小结全部内容了,希望大家多多支持我们~

  • sqlserver分页查询处理方法小结

    sqlserver2008不支持关键字limit ,所以它的分页sql查询语句将不能用MySQL的方式进行,幸好sqlserver2008提供了top,rownumber等关键字,这样就能通过这几个关键字实现分页. 下面是本人在网上查阅到的几种查询脚本的写法: 几种sqlserver2008高效分页sql查询语句 top方案: sql code: select top 10 * from table1 where id not in(select top 开始的位置 id from table1

  • c++获取sqlite3数据库表中所有字段的方法小结

    常用方法: 1.使用sqlite3_get_table函数 2.获取sqlite创建表的sql语句字符串,然后进行解析获取到相应的字段 3.采用配置文件的方式,将所有字段名写入配置文件 下面针对这三个方法给大家逐一详细介绍. 方法1:使用sqlite3_get_table函数 代码: char *dbname = "test.db"; int rc = sqlite3_open(dbname, &db); if (rc == SQLITE_OK) { char sql[256]

  • SQL Server 常用函数使用方法小结

    之前就想要把一些 SQL 的常用函数记录下来,不过一直没有实行...嘿嘿... 直到今天用到substring()这个函数,C# 里面这个方法起始值是 0,而 SQL 里面起始值是 1.傻傻分不清楚... 这篇博客作为记录 SQL 的函数的使用方法,想到哪里用到哪里就写到哪里... SubString():用于截取指定字符串的方法.该方法有三个参数: 参数1:用于指定要操作的字符串. 参数2:用于指定要截取的字符串的起始位置,起始值为 1 . 参数3:用于指定要截取的长度. select sub

  • Nginx实现404页面的方法小结

    第一种:Nginx自己的错误页面 Nginx访问一个静态的html 页面,当这个页面没有的时候,Nginx抛出404,那么如何返回给客户端404呢? 看下面的配置,这种情况下不需要修改任何参数,就能实现这个功能. server { listen 80; server_name www.test.com; root /var/www/test; index index.html index.htm; location / { } # 定义错误页面码,如果出现相应的错误页面码,转发到那里. erro

  • Java中Spring获取bean方法小结

    Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢? Bean工厂(com.springframework.beans.factory.BeanFactory)是Spring框架最核心的接口,它提供了高级IoC的配置机制.BeanFactory使管理不同类型的Java对象成为可能,应用上下文(com.springframework.context.ApplicationContext)建立在BeanFactory基础之上,提供

随机推荐