乐趣区

关于golang:Go-118-新特性多模块工作区教程让多模块开发变得简单

导读

  • 随着 2020 年 3 月 15 日 go 1.18 正式公布,新版本除了对性能的晋升之外,还引入了很多新性能,其中就有 go 期盼已久的性能泛型 (Generics),同时还引入的多模块工作区(Workspaces) 和含糊测试(Fuzzing)。
  • 对于泛型网上曾经有很多介绍的教程了,这里我介绍一个实用的性能,多模块工作区的应用办法和教程。
  • Go 多模块工作区可能使开发者可能更容易地同时解决多个模块的工作,如:

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

目录

  • 多模块工作区
  • 开发流程演示
  • 总结
  • 参考文献

多模块工作区

阐明

  • go 应用的是多模块工作区,能够让开发者更容易同时解决多个模块的开发。在 Go 1.17 之前,只能应用 go.mod replace 指令来实现,如果你正巧是同时进行多个模块的开发,应用它可能是很苦楚的。每次当你想要提交代码的时候,都不得不删除掉 go.mod 中的 replace 能力使模块稳固的公布版本。
  • 在应用 go 1.18 多模块工作区性能的时候,就应用这项工作变得简略容易解决。上面我来介绍怎么应用这一性能。
  • Go 多模块工作区文档、代码示例获取地址 https://github.com/link1st/li…

应用条件

  • 首先 咱们须要 go 1.18 或更高版本 go 装置
# 查看 go 版本
> go version
go version go1.18 darwin/amd64

go work 反对命令

  • 通常状况下,倡议不要提交 go.work 文件到 git 上,因为它次要用于本地代码开发。
  • 举荐在: $GOPATH 门路下执行,生成 go.work 文件
  • go work init 初始化工作区文件,用于生成 go.work 工作区文件

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

  • go work use 增加新的模块到工作区

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

  • go work edit 用于编辑 go.work 文件

    能够应用 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 sync 将工作区的构建列表同步到工作区的模块
  • go env GOWORK

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

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

go.work 文件构造

  • 文件构造和 go.mod 文件构造相似,反对 Go 版本号、指定工作区和须要替换的仓库
  • 文件构造示例:
go 1.18

use (
    ./hello
    ./example
)

replace (github.com/link1st/example => ./example1)
use 指定应用的模块目录
  • 能够应用 go work use hello 增加模块,也能够手动批改 go.work 工作区增加新的模块
  • 在工作区中增加了模块门路,编译的时候会主动应用 use 中的本地代码进行代码编译,和 replaces 性能相似。
# 单模块构造
use ./hello

# 多模块构造
use (
    ./hello
    ./example
)
replaces 替换依赖仓库地址
  • replaces 命令与 go.mod 指令雷同,用于替换我的项目中依赖的仓库地址
  • 须要留神的是 replacesuse 不能同时指定雷同的本地门路

同时指定报错信息:
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.workgo.mod replace 性能的的时候别离指定不同的代码仓库门路,go.work 优先级高于 go.mod 中定义

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

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

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

replace (github.com/link1st/example => ./example1)
  • 在代码构建时候应用的是 go.work 指定的 example1 仓库的代码,go.work 优先级别更高

如何应用

  • 在 Go 1.18 go rungo build 都会默认应用工作区性能
  • GOWORK 也能够指定配置 go.work 文件地位
export GOWORK="~/go/src/test/go.18/workspace/go.work"

如何禁用工作区

  • Go 全局变量 GOWORK 设置 off 则能够禁用工作区性能

    export GOWORK=off

开发流程演示

  • 演示如何应用多模块工作区性能。在当初微服务流行的年代,一个人会保护多个代码仓库,很多的时候是多个仓库进行同时开发
  • 假如咱们当初进行 hello 仓库开发,实现的性能是,实现将输出的字符串反转并输入,字符串反转性能依赖于 github.com/link1st/example (下文统称 example)公共仓库实现
  • 新建 hello 我的项目
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
  • 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"go run github.com/link1st/link1st/workspaces/hello -str "hello world" 能够看到输入了 hello world 反转当前的字符串
> go run main.go -str "hello world"
dlrow olleh
  • 到这里,最后的性能曾经实现,然而后续需要变动,不仅须要输入反转当前的字符串,还须要将字符串大写
  • 咱们则须要去 example 仓库中增加开发 将字符串大写的性能
# 回到工作根目录,将 common 代码下载到本地进行增加新的性能
# 下载依赖的 example 包
git clone git@github.com:link1st/example.git
# 在 example 包中增加 字符串大学的性能
  • vim example/stringutil/to_upper.go 代码如下
// 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)
}
  • 因为代码还在本地调试,未提交 git 仓库中,这个时候就须要用到 Go 多模块工作区的性能了。
  • 进入我的项目根目录,初始化咱们当初正在开发的模块
# 初始化 go.work 文件
go work init  ./hello ./example
# 查看 go.work 文件内容
cat go.work
  • 文件构造如下
go 1.18

use (
    ./example
    ./hello
)
  • 回到 hello 我的项目,vim main.go 将字符串大写的性能增加上。
func main() {
    ...

    // 调用公共仓库,进行字符串反转
    str = stringutil.Reversal(str)
    // 减少字符大写的性能
    str = stringutil.ToUpper(str)
    // 输入反转后的字符串
    fmt.Println(str)
    
    ...
}
  • 运行代码

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

go run main.go -str "hello world"
DLROW OLLEH
  • 到这里,演示的代码曾经全副实现

总结

  • 应用 Go 多模块工作区的性能,能够让咱们轻松在多个模块之间切换工作,更能适应古代微服务架构开发。

参考文献

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

Go 1.18 is released!

Tutorial: Getting started with multi-module workspaces

go-1.18-features

退出移动版