go语言中,从1.11开始,引入module,进行版本管理。

通过使用module,工程目录的位置不用必须放在GOPATH下。

本文介绍 module的使用。

下文中用的Go版本是1.13。

1. go mod命令

通过go mod可以进行modules的相关操作。

首先看下 go mod命令:

$ go help mod
Go mod provides access to operations on modules. Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality. Usage: go mod <command> [arguments] The commands are: download download modules to local cache // 下载依赖的module到本地cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory // 在当前目录下初始化新的module
tidy add missing and remove unused modules // 添加缺失的module,移出不用的module
vendor make vendored copy of dependencies // 将依赖复制到vendor下
verify verify dependencies have expected content
why explain why packages or modules are needed Use "go help mod <command>" for more information about a command.

2.使用module举例

2.1 定义module

在任意目录下创建工程目录,可以不是GOPATH路径下。

$ mkdir hello_mysql
$ pwd
/home/lanyang/workspace/go_example/hello_mysql $ go mod init hello_mysql
go: creating new go.mod: module hello_mysql $ ll
-rw-rw-r--. 1 lanyang lanyang 28 Dec 21 18:25 go.mod $ cat go.mod
module hello_mysql go 1.13

新建源码文件 main.go, 内容如下:

// main.go

package main

import (
"database/sql"
"log" _ "github.com/go-sql-driver/mysql" ) var DB *sql.DB
var dataBase = "root:Aa123456@tcp(192.168.0.101:3306)/?timeout=5s&readTimeout=6s" func mysqlInit() {
var err error
DB, err = sql.Open("mysql", dataBase)
if err != nil {
log.Fatalln("open db fail:", err)
} } func main() {
mysqlInit() execSql()
} func execSql() {
var value int
err := DB.QueryRow("select 1").Scan(&value)
if err != nil {
log.Println("query failed:", err)
return
} log.Println("value:", value)
}

以上代码实现连接MySQL服务器,执行简单的SQL语句。

2.2 编译

$ go build
go: downloading github.com/go-sql-driver/mysql v1.4.1
go: extracting github.com/go-sql-driver/mysql v1.4.1
go: finding github.com/go-sql-driver/mysql v1.4.1 $ ll
total 5788
-rw-rw-r--. 1 lanyang lanyang 75 Dec 22 16:57 go.mod
-rw-rw-r--. 1 lanyang lanyang 179 Dec 22 16:57 go.sum
-rwxrwxr-x. 1 lanyang lanyang 5912033 Dec 22 16:58 hello_mysql
-rw-rw-r--. 1 lanyang lanyang 669 Dec 22 16:57 main.go

在Go 1.13中,继续使用临时环境变量GO111MODULE来设置是否使用module。

GO111MODULE 可设置为off, on, 或auto (默认)。

如果 GO111MODULE=auto 或没有设置, go command(即go build, go test go get等)是否使用module取决于是否存在go.mod文件。

如果当前目录,或父目录中存在go.mod文件,那么go command就会使用module,否则不会使用module。

例子中,没有设置GO111MODULE,保持默认值。

通过定义module,已经创建了go.mod文件,这样,执行go command的时候,就会使用module 查找和下载依赖包,并将依赖包信息添加到go.mod文件中。

下载的依赖包放在$GOPATH/pkg/mod

$ ll $GOPATH/pkg/mod/
total 8
drwxrwxr-x. 3 lanyang lanyang 4096 Dec 22 16:58 cache
drwxrwxr-x. 3 lanyang lanyang 4096 Dec 22 16:58 github.com

go.mod文件内容被修改为:

module hello_mysql

go 1.13

require github.com/go-sql-driver/mysql v1.4.1

编译后,创建可执行文件hello_mysql,执行:

$ ./hello_mysql
2019/12/22 17:19:19 value: 1

3.module 与 vendor

为了兼容老版本,或者想把所有的依赖包放在一个目录下,可以使用go mod vendor

go mod vendor会在根目录下创建 vendor目录,里面存放所有的依赖包。

编译的时候,加上选项-mod=vendor,就可以使用vendor目录下的依赖包。

继续使用上面的例子。

清理pkg/mod:

$ rm -rf $GOPATH/pkd/mod

例子代码目录下,只保留go.modmain.go

使用vendor存放依赖包,执行go mod vendor:

$ go mod vendor
go: downloading github.com/go-sql-driver/mysql v1.4.1
go: extracting github.com/go-sql-driver/mysql v1.4.1
go: finding google.golang.org/appengine v1.6.5
go: downloading google.golang.org/appengine v1.6.5
go: extracting google.golang.org/appengine v1.6.5 $ ll
total 16
-rw-rw-r--. 1 lanyang lanyang 128 Dec 22 17:23 go.mod
-rw-rw-r--. 1 lanyang lanyang 1034 Dec 22 17:23 go.sum
-rw-rw-r--. 1 lanyang lanyang 669 Dec 22 17:19 main.go
drwxrwxr-x. 4 lanyang lanyang 4096 Dec 22 17:23 vendor

vendor目录以及go.sum文件被创建。

查看go.mod文件,内容被修改为:

module hello_mysql

go 1.13

require (
github.com/go-sql-driver/mysql v1.4.1
google.golang.org/appengine v1.6.5 // indirect
)

查看下vendor目录的内容:

$ ll vendor/
total 12
drwxrwxr-x. 3 lanyang lanyang 4096 Dec 22 17:23 github.com
drwxrwxr-x. 3 lanyang lanyang 4096 Dec 22 17:23 google.golang.org
-rw-rw-r--. 1 lanyang lanyang 145 Dec 22 17:23 modules.txt

可以看到目录下存放着所有的依赖包。

编译时,添加-mod=vendor

$ go build -mod=vendor
$ ll
total 5792
-rw-rw-r--. 1 lanyang lanyang 128 Dec 22 17:23 go.mod
-rw-rw-r--. 1 lanyang lanyang 1034 Dec 22 17:23 go.sum
-rwxrwxr-x. 1 lanyang lanyang 5912033 Dec 22 17:34 hello_mysql
-rw-rw-r--. 1 lanyang lanyang 669 Dec 22 17:19 main.go
drwxrwxr-x. 4 lanyang lanyang 4096 Dec 22 17:23 vendor

此时,就会在vendor中查找依赖包。

执行:

$ ./hello_mysql
2019/12/22 17:36:40 value: 1

这种方式中,既使用了module特性,摆脱了工程目录对GOPATH的依赖,又使用了vendor存放依赖包。

尤其是在上线前的编译和打包阶段,提前在vendor目录存放依赖包,就可以不用再通过网络去下载,避免了网络不稳定的影响,从而可以节省大量的时间。

4.参考

关于go module

go mod 使用

Go Module 入门使用

go module 使用举例的更多相关文章

  1. npm手册

    npm现在都是随同NodeJS一起安装的包管理和分发工具,所以npm的安装,只要下载新版的nodejs已经集成了npm. 安装好了以后,直接输入npm或者npm help,会出来一些npm自带的命令. ...

  2. grunt使用一步一步讲解

    grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...

  3. 【盗墓笔记】图解使用fat-aar方式在AndroidStudio中打包嵌套第三方aar的aar

    将一些项目中的一些独立功能打包成aar,不仅能于项目解耦,还能够提供给其它项目使用相同的功能,可谓是为项目开发带来了很大的便利.最近第一次做sdk,碰到一些问题,花了不少时间才解决,所以这里做一下简单 ...

  4. angular源码阅读,依赖注入的原理:injector,provider,module之间的关系。

    最开始使用angular的时候,总是觉得它的依赖注入方式非常神奇. 如果你跳槽的时候对新公司说,我曾经使用过angular,那他们肯定会问你angular的依赖注入原理是什么? 这篇博客其实是angu ...

  5. module.export和export

    module.exports 和 exports 是引用到的同一个对象,类似下面代码所示(为了举例,不是完全的正确): var module.exports = {};        var expo ...

  6. 一步一步学Python(1) 基本逻辑控制举例和编码风格规范

    (1) 基本逻辑控制举例和编码风格规范 1.while死循环 2.for循环 3.if,elif,else分支判断 4.编码风格(官方建议) 版本:Python3.4 1.while死循环 #func ...

  7. python yield用法举例说明

    1  yield基本用法 典型的例子: 斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到.1 2 3 5 8…… def fab(ma ...

  8. Linux下c函数dlopen实现加载动态库so文件代码举例

    dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了. ...

  9. linux driver module

    本文将对Linux系统中的sysfs进行简单的分析,要分析sysfs就必须分析内核的driver-model(驱动模型),两者是紧密联系的.在分析过程中,本文将以platform总线和spi主控制器的 ...

随机推荐

  1. jQuery EasyUI简介

    jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用户界面插件. jQuery EasyUI是一组基于jQuery的UI插件集合体,而jQuery EasyUI的目标就是帮助we ...

  2. 运行tomcat7w.exe提示指定的服务未安装 解决办法

    一.问题重现点击bin下tomcat7w.exe出现如下提示:提示指定的服务未安装 二.原因分析tomcat7.exe和tomcat7w.exe要起作用必须先为这两个文件安装服务.其中tomcat7. ...

  3. 二、MySQL介绍

    目录 一.MySQL背景 二.MySQL的优点 三.MySQL安装 四.MySQL服务的启动和停止 五.MySQL登录和退出 六.MySQL常用命令 (一)常用命令 (二)语法规范 (三)SQL语言细 ...

  4. Image Processing and Computer Vision_Review:Recent Advances in Features Extraction and Description Algorithms: A Comprehensive Survey——2017.03

    翻译 特征提取和描述算法的最新进展:全面的调查 摘要 - 计算机视觉是当今信息技术中最活跃的研究领域之一.让机器和机器人能够以视线的速度看到和理解周围的世界,创造出无穷无尽的潜在应用和机会.特征检测和 ...

  5. VMware无法连接MKS:套接字连接尝试次数太多解决

    粘贴自:https://jingyan.baidu.com/article/425e69e61eb578be15fc16ae.html VMware在开启虚拟机的时候,突然弹出[无法连接MKS:套接字 ...

  6. 蓝桥杯BASIC-13 数列排序

    问题描述 给定一个长度为n的数列,将这个数列按从小到大的顺序排列.1<=n<=200 输入格式 第一行为一个整数n. 第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000. 输 ...

  7. Make It Connected CodeForces - 1095F (建图+最小生成树)

    Make It Connected CodeForces - 1095F You are given an undirected graph consisting of nn vertices. A ...

  8. javascript只弹出一次框 再次刷新不弹出

    .打开页面自动弹出  当关闭弹框的时候  设置cookie生存时间  再次刷新页面判断cookie是否失效 <html> <head> <meta charset=&qu ...

  9. json.loads 报错 json.decoder.JSONDecodeError

    json.loads报json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes 出现这个错误其实只 ...

  10. 题解 [AT2134] Zigzag MST

    题面 解析 我们先考虑一下加一条边(x,y,z)会成什么亚子: (还有很多边不画了...) 然后我们把这个图单独拿出来: 我们可以发现,对于最小生成树的贡献, 它是等价于下面这张图的(因为连通性一样) ...