Go module和workspaces

146 阅读1分钟

Module

go module是Go1.11版本之后官方推出的版本管理工具,并且从Go1.13版本开始,go module成为了Go语言默认的依赖管理工具。

重要环境变量

GO111MODULE

GO111MODULE是用于控制go module工作模式的环境变量,它有三个可选值:

  1. off 禁用,编译时从GOPATHvendor中查找依赖包。
  2. on 启用,编译时只更具go.mod管理依赖。
  3. auto 自动,当项目不在$GOPATH/src下,并且项目根目录有go.mod文件时,开启模块支持。

GOPROXY

GOPROXY用于配置下载依赖的代理地址,默认值为https://proxy.golang.org,但对于国内用户不是很友好。 可以使用其他镜像源替代,如goproxy.cn

go env -w GOPROXY=https://goproxy.cn,direct

此外还有

https://mirrors.aliyun.com/goproxy

https://goproxy.io

https://gocenter.io

...

go mod常用命令

  • go mod init xxx 初始化当前文件夹, 创建go.mod文件 xxx为希望的module名
  • go mod tidy 增加缺少的module,删除无用的module
  • go mod vendor 将依赖复制到vendor下
  • 其他命令看使用go mod help自行查看

go.mod文件

例子

module github.com/Q1mi/studygo/blogger

go 1.12

require (
	github.com/DeanThompson/ginpprof v0.0.0-20190408063150-3be636683586
    github.com/gin-gonic/gin v1.4.0
	github.com/go-sql-driver/mysql v1.4.1
	github.com/jmoiron/sqlx v1.2.0
	github.com/satori/go.uuid v1.2.0
	google.golang.org/appengine v1.6.1 // indirect
)


replace (
	github.com/gin-gonic/gin v1.4.0 => ../gin-gonic/gin
)
  • module 用于定义包名,或者叫模块名
  • require 用于指定依赖包
  • replace 用于重定向,如示例中重定向到本地。一般用于解决外网访问问题。
  • indirect 表示间接引用

go get命令

在项目中执行go get命令可以下载依赖包,并且还可以指定下载的版本。

  1. go get -u将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
  2. go get -u=patch将会升级到最新的修订版本
  3. go get package@version将会升级到指定的版本号version 如果下载所有依赖可以使用go mod download命令。

其他操作

  • 格式化go.mod文件 在手动修改go.mod文件后,使用go mod edit -fmt格式化go.mod文件
  • 命令行重定向包 go mod edit -replace=golang.org/x/crypto@v0.0.0=github.com/golang/crypto@latest
  • 清理module缓存 go clean -modcache
  • 查看可下载的包版本 go list -m -versions xxx
  • 使用最新包 慎用
require (
	github.com/DeanThompson/ginpprof latest
	github.com/gin-gonic/gin latest
)

Workspaces

go 1.18后,使用workspaces支持开发者同时在多个module中间进行编码(不需要修改go.mod文件),可以方方便的进行编译运行等工作。常用于common组件开发,如日志库、错误库等等。

常用命令

  • go workgo help work 查看帮助文档。
  • go work init 初始化workspaces文件,创建一个go.work文件,并将添加指定文件夹中的module。go work init .\hello
  • go work use 添加新的module到go.work文件中。go work use .\example

实际操作

  1. 创建 workspace工作目录
$ mkdir workspace
$ cd workspace
  1. 创建hello module
$ mkdir hello
$ cd hello
$ go mod init example.com/hello
go: creating new go.mod: module example.com/hello

使用 go get 添加 golang.org/x/example 依赖

$ go get golang.org/x/example

hello文件夹下添加hello.go

package main

import (
    "fmt"

    "golang.org/x/example/stringutil"
)

func main() {
    fmt.Println(stringutil.Reverse("Hello"))
}

执行 go run example.com/hello,得到反转后的字符串:olleH 3. 初始化workspaces文件 回到workspce目录下,执行

$ go work init ./hello

产生一个go.work文件,内容如下。

go 1.18

use ./hello
  1. 添加依赖exampleworkspace目录下,克隆仓库
$ git clone https://go.googlesource.com/example
Cloning into 'example'...
remote: Total 165 (delta 27), reused 165 (delta 27)
...

如果存在网络问题,可以使用https://github.com/golang/example

添加新moduel

go work use ./example

此时,go.work文件会增加example相关信息。

go 1.18

use (
	./example
	./hello
)
  1. 修改本地代码进行测试 在 workspace/example/stringutil 目录下创建一个新文件 toupper.go
package stringutil

import "unicode"

// ToUpper uppercases all the runes in its argument string.
func ToUpper(s string) string {
    r := []rune(s)
    for i := range r {
        r[i] = unicode.ToUpper(r[i])
    }
    return string(r)
}

修改workspace/hello/hello.go代码如下:

package main

import (
    "fmt"

    "golang.org/x/example/stringutil"
)

func main() {
    fmt.Println(stringutil.ToUpper("Hello"))
}

运行测试

$ go run example.com/hello
HELLO

参考资料