golang

Go 1.18 新特性多模块工作区教程-让多模块开发变得简单

2022-03-21  本文已影响0人  link1st

导读

方便进行依赖的代码调试(打断点、修改代码)、排查依赖代码 bug
方便同时进行多个仓库/模块并行开发调试

目录

多模块工作区

说明

使用条件

# 查看 go 版本
> go version
go version go1.18 darwin/amd64

go work 支持命令

初始化并写入一个新的 go.work 到当前路径下,可以指定需要添加的代码模块
示例: go work init ./hello 将本地仓库 hello 添加到工作区
hello 仓库必须是 go mod 依赖管理的仓库(./hello/go.mod 文件必须存在)

命令示例:
go work use ./example 添加一个模块到工作区
go work use ./example ./example1 添加多个模块到工作区
go work use -r ./example 递归 ./example 目录到当前工作区
删除命令使用 go work edit -dropuse=./example 功能

可以使用 edit 命令编辑和手动编辑 go.work 文件效果是相同的
示例:
go work edit -fmt go.work 重新格式化 go.work 文件
go work edit -replace=github.com/link1st/example=./example go.work 替换代码模块
go work edit -dropreplace=github.com/link1st/example 删除替换代码模块
go work edit -use=./example go.work 添加新的模块到工作区
go work edit -dropuse=./example go.work 从工作区中删除模块

查看环境变量,查看当前工作区文件路径
可以排查工作区文件是否设置正确,go.work 路径找不到可以使用 GOWORK 指定

> go env GOWORK
$GOPATH/src/link1st/link1st/workspaces/go.work

go.work 文件结构

go 1.18

use (
    ./hello
    ./example
)

replace (
    github.com/link1st/example => ./example1
)

use 指定使用的模块目录
# 单模块结构
use ./hello

# 多模块结构
use (
    ./hello
    ./example
)
replaces 替换依赖仓库地址

同时指定报错信息:
go: workspace module github.com/link1st/example is replaced at all versions in the go.work file. To fix, remove the replacement from the go.work file or specify the version at which to replace the module.

同时在 usereplace 指定相同的本地路径

go 1.18

use (
    ./hello
    ./example
)

replace (
    github.com/link1st/example => ./example
)

go.work 文件优先级高于 go.mod 中定义

go.mod 中定义替换为本地仓库 example

replace (
    github.com/link1st/example => ./example1
)

go.work 中定义替换为本地仓库 example1

replace (
    github.com/link1st/example => ./example1
)

如何使用

export GOWORK="~/go/src/test/go.18/workspace/go.work"

如何禁用工作区

export GOWORK=off

开发流程演示

mkdir hello
cd hello
# 代码仓库启动 go mod 依赖管理,生成 go.mod 文件
go mod init github.com/link1st/link1st/workspaces/hello
# 下载依赖包
go get github.com/link1st/example
# 编写 main 文件
vim main.go
// Package main main 文件,go 多模块工作区演示代码
// 实现将输入的字符串反转输出并输出
package main

import (
    "flag"
    "fmt"

    "github.com/link1st/example/stringutil"
)

var (
    str = ""
)

func init() {
    flag.StringVar(&str, "str", str, "输入字符")
    flag.Parse()
}

func main() {
    if str == "" {
        fmt.Println("示例: go run main.go -str hello")
        fmt.Println("str 参数必填")
        flag.Usage()
        return
    }

    // 调用公共仓库,进行字符串反转
    str = stringutil.Reversal(str)
    // 输出反转后的字符串
    fmt.Println(str)
    return
}


> go run main.go -str "hello world"
dlrow olleh
# 回到工作根目录,将 common 代码下载到本地进行添加新的功能
# 下载依赖的 example 包
git clone git@github.com:link1st/example.git
# 在 example 包中添加 字符串大学的功能

// Package stringutil stringutil
package stringutil

import (
    "unicode"
)

// ToUpper 将字符串进行大写
func ToUpper(s string) string {
    r := []rune(s)
    for i := range r {
        r[i] = unicode.ToUpper(r[i])
    }
    return string(r)
}

# 初始化 go.work 文件
go work init  ./hello ./example
# 查看 go.work 文件内容
cat go.work
go 1.18

use (
    ./example
    ./hello
)
func main() {
    ...

    // 调用公共仓库,进行字符串反转
    str = stringutil.Reversal(str)
    // 增加字符大写的功能
    str = stringutil.ToUpper(str)
    // 输出反转后的字符串
    fmt.Println(str)
    
    ...
}

可以看到输出了反转并 大写 的字符串,大写的函数功能只在本地,未提交到 git 上,这样我们就实现了可以同时在两个模块上并行开发

go run main.go -str "hello world"
DLROW OLLEH

总结

参考文献

Go 1.18 新特性多模块工作区教程

Go 1.18 is released!

Tutorial: Getting started with multi-module workspaces

go-1.18-features

上一篇下一篇

猜你喜欢

热点阅读