GithubHelp home page GithubHelp logo

cubxxw / go-mod Goto Github PK

View Code? Open in Web Editor NEW
3.0 2.0 1.0 21 KB

🏄‍♂️ 用来学习Go语言的mod包管理工具,包括go1.18新特性workspaces使用。 并且提供包和笔记分享学习

Go 33.43% Shell 66.57%
gomodule mod workspaces

go-mod's Introduction

Go-mod包 & 多模块工作区(Workspaces)

[toc]

⚡ go mod

包的导入方式

  1. 绝对路径导入(在GOPATH目录中导入包)

  2. 相对路径导入(不建议!!!)

  3. 点导入

    • 相当于直接复制源文件过来,此时不需要用.

      Println("hello word")
      
  4. 别名导入

  5. 下划线导入

Go-mod方式管理包

优势:

  • 代码可以放在任意位置,不用设置GOPATH
  • 自动下载依赖管理
  • 版本控制
  • 不允许使用相对导入
  • replace机制(goproxy代理机制)

项目开始~

为了理清关系,这一节从头开始做

目录结构

image-20220525220447501

我们的项目就叫go-mod

mkdir go-mod
cd go-mod
mkdir hello

为代码启用依赖项跟踪

需要设置名字,一般和报名是一样的

PS C:\Users\smile\Desktop\区块链\code\go-mod> go mod init go-mod
go: creating new go.mod: module go-mod
go: to add module requirements and sums:
        go mod tidy

查看模块

module go-mod

go 1.18

编辑hello.go

package main

import "fmt"

func main() {
	fmt.Println("hello word")
}

编译:

PS C:\Users\smile\Desktop\区块链\code\go-mod\hello> go run . 
hello word

目录结构

PS C:\Users\smile\Desktop\区块链\code\go-mod> tree
卷 系统 的文件夹 PATH 列表
卷序列号为 DE95-1D97
C:.
├─hello
└─main

PS C:\Users\smile\Desktop\区块链\code\go-mod> cd .\main\
PS C:\Users\smile\Desktop\区块链\code\go-mod\main> New-Item main.go            

    目录: C:\Users\smile\Desktop\区块链\code\go-mod\main

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2022/5/25     21:32              0 main.go

创建一个包文件夹,创建一个文件task.go

PS C:\Users\smile\Desktop\区块链\code\go-mod> mkdir models


    目录: C:\Users\smile\Desktop\区块链\code\go-mod


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2022/5/25     22:00                models

PS C:\Users\smile\Desktop\区块链\code\go-mod> New-Item task.go

    目录: C:\Users\smile\Desktop\区块链\code\go-mod

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2022/5/25     22:02              0 task.go

主函数

package main

import (
	. "fmt"
	"go-mod/hello"
	"go-mod/models"
)

func main() {
	Println("main主函数")
	hello.Hello()
	Println(models.Name)
	//hello.Hello()
}

编译:

PS C:\Users\smile\Desktop\区块链\code\go-mod> go run .\main.go
main主函数
hello word
test

所出现问题

文件mod包嵌入使用的问题,导致mod机制没办法正常在子目录使用~

github导入包

package models

import "fmt"
import "github.com/astaxie/beego"

var Name = "test"

func init() {
	fmt.Println("最先开始调用多个")
}

func main() {
	beego.Run()
}

回到主目录

PS C:\Users\smile\Desktop\区块链\code\go-mod>  go get github.com/astaxie/beego

下载依赖,查看go-mod

module go-mod

go 1.18

require (
	github.com/astaxie/beego v1.12.3 // indirect
	github.com/beorn7/perks v1.0.1 // indirect
	github.com/cespare/xxhash/v2 v2.1.1 // indirect
	github.com/golang/protobuf v1.4.2 // indirect
	github.com/hashicorp/golang-lru v0.5.4 // indirect
	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
	github.com/prometheus/client_golang v1.7.0 // indirect
	github.com/prometheus/client_model v0.2.0 // indirect
	github.com/prometheus/common v0.10.0 // indirect
	github.com/prometheus/procfs v0.1.3 // indirect
	github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
	golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
	golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
	golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 // indirect
	golang.org/x/text v0.3.0 // indirect
	google.golang.org/protobuf v1.23.0 // indirect
	gopkg.in/yaml.v2 v2.2.8 // indirect
)

还有一个go sum文件

远程推送到github上

  1. 在github上新建一个项目Go-mod
  2. go mod init github.com/3293172751/go-mod
  3. 添加readme.m

⚡ go workspace

Why you need it?

::: tip 在参与sealos工程的时候,它们用到了Go语言新特性:Workspaces

由于sealos使用的是go1.18的workspace特性,添加新模块后,需要go work usr -r .在root目录下运行更新同步的workspace。

我们这篇来学习和使用这个新特性

:::

Go 多模块工作区能够使开发者能够更容易地同时处理多个模块的工作,如:

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

简单上手

当前目录结构

image-20221120151919161

文件内容

mod包内容:

module nsddd.top/mszlu-common

go 1.19

-----------

module nsddd.top/fly-fish

go 1.19

对应文件:

mszlu-common/utils.go

package utils

import (
	"fmt"
)

func Print() {
	fmt.Println("这是utils.go")

	//调用fly-fish的main.go
 
}

fly-fish/main.go

package main

import "fmt"

func main() {
	fmt.Println("这是fly-fish的main.go")
}

如何调用

我们希望调用另一个 mod 模块的函数,我们使用work

go work init ./fly-fish

使用fly-fish

我们再加入一个工作区:

go work use ./mszlu-common

此时工作目录文件:go.work

go 1.19

use (
	./fly-fish
	./mszlu-common
)

调用 utils

fly-fish/main.go

package main

import (
	"fmt"

	utils "nsddd.top/mszlu-common"
)

func main() {
	fmt.Println("这是fly-fish的main.go")
	utils.Print()
}

🚀 编译结果如下:

[Running] go run "c:\Users\smile\Desktop\test\fly-fish\main.go"
这是fly-fish的main.go
这是utils.go

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 [email protected]: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-mod's People

Contributors

cubxxw avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

go-mod's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.