{"id":16475083,"url":"https://github.com/cubxxw/go-mod","last_synced_at":"2026-07-02T20:02:16.450Z","repository":{"id":135947806,"uuid":"496265602","full_name":"cubxxw/go-mod","owner":"cubxxw","description":"🏄‍♂️ 用来学习Go语言的mod包管理工具，包括go1.18新特性workspaces使用。 并且提供包和笔记分享学习","archived":false,"fork":false,"pushed_at":"2022-11-20T08:59:29.000Z","size":21,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-08T10:41:33.261Z","etag":null,"topics":["gomodule","mod","workspaces"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cubxxw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-25T14:27:22.000Z","updated_at":"2024-03-26T12:02:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"bf32907a-04d8-4adc-96c6-75b7d030af71","html_url":"https://github.com/cubxxw/go-mod","commit_stats":null,"previous_names":["3293172751/go-mod"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cubxxw/go-mod","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubxxw%2Fgo-mod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubxxw%2Fgo-mod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubxxw%2Fgo-mod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubxxw%2Fgo-mod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cubxxw","download_url":"https://codeload.github.com/cubxxw/go-mod/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cubxxw%2Fgo-mod/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35060913,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gomodule","mod","workspaces"],"created_at":"2024-10-11T12:36:02.088Z","updated_at":"2026-07-02T20:02:16.427Z","avatar_url":"https://github.com/cubxxw.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go-mod包 \u0026 多模块工作区（Workspaces）\n\n[toc]\n\n\n\n## ⚡ go mod\n\n### 包的导入方式\n\n1. 绝对路径导入（在GOPATH目录中导入包）\n\n2. 相对路径导入（不建议！！！）\n\n3. 点导入\n\n   + 相当于直接复制源文件过来，此时不需要用.\n\n     ```\n     Println(\"hello word\")\n     ```\n\n4. 别名导入\n\n5. 下划线导入\n\n\n\n### Go-mod方式管理包\n\n#### 优势：\n\n- **代码可以放在任意位置，不用设置GOPATH**\n- **自动下载依赖管理**\n- **版本控制**\n- **不允许使用相对导入**\n- **replace机制（goproxy代理机制）**\n\n\n\n\n\n### 项目开始~\n\n\u003e 为了理清关系，这一节从头开始做\n\n**目录结构**\n\n![image-20220525220447501](https://s2.loli.net/2022/05/25/eKIV2UnTLjcWRJC.png)\n\n**我们的项目就叫go-mod**\n\n```\nmkdir go-mod\ncd go-mod\nmkdir hello\n```\n\n### 为代码启用依赖项跟踪\n\n**需要设置名字，一般和报名是一样的**\n\n```\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e go mod init go-mod\ngo: creating new go.mod: module go-mod\ngo: to add module requirements and sums:\n        go mod tidy\n```\n\n**查看模块**\n\n```\nmodule go-mod\n\ngo 1.18\n```\n\n**编辑hello.go**\n\n```\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"hello word\")\n}\n```\n\n**编译：**\n\n```\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\\hello\u003e go run . \nhello word\n```\n\n\n\n**目录结构**\n\n```bash\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e tree\n卷 系统 的文件夹 PATH 列表\n卷序列号为 DE95-1D97\nC:.\n├─hello\n└─main\n\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e cd .\\main\\\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\\main\u003e New-Item main.go            \n\n    目录: C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\\main\n\nMode                 LastWriteTime         Length Name\n----                 -------------         ------ ----\n-a----         2022/5/25     21:32              0 main.go\n```\n\n\n\n**创建一个包文件夹,创建一个文件task.go**\n\n```\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e mkdir models\n\n\n    目录: C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\n\n\nMode                 LastWriteTime         Length Name\n----                 -------------         ------ ----\nd-----         2022/5/25     22:00                models\n\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e New-Item task.go\n\n    目录: C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\n\nMode                 LastWriteTime         Length Name\n----                 -------------         ------ ----\n-a----         2022/5/25     22:02              0 task.go\n```\n\n\n\n**主函数**\n\n```\npackage main\n\nimport (\n\t. \"fmt\"\n\t\"go-mod/hello\"\n\t\"go-mod/models\"\n)\n\nfunc main() {\n\tPrintln(\"main主函数\")\n\thello.Hello()\n\tPrintln(models.Name)\n\t//hello.Hello()\n}\n```\n\n**编译：**\n\n```\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e go run .\\main.go\nmain主函数\nhello word\ntest\n```\n\n\n\n\n\n### 所出现问题\n\n文件mod包嵌入使用的问题，导致mod机制没办法正常在子目录使用~\n\n\n\n### github导入包\n\n```go\npackage models\n\nimport \"fmt\"\nimport \"github.com/astaxie/beego\"\n\nvar Name = \"test\"\n\nfunc init() {\n\tfmt.Println(\"最先开始调用多个\")\n}\n\nfunc main() {\n\tbeego.Run()\n}\n```\n\n**回到主目录**\n\n```\nPS C:\\Users\\smile\\Desktop\\区块链\\code\\go-mod\u003e  go get github.com/astaxie/beego\n```\n\n**下载依赖，查看go-mod**\n\n```\nmodule go-mod\n\ngo 1.18\n\nrequire (\n\tgithub.com/astaxie/beego v1.12.3 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.1.1 // indirect\n\tgithub.com/golang/protobuf v1.4.2 // indirect\n\tgithub.com/hashicorp/golang-lru v0.5.4 // indirect\n\tgithub.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect\n\tgithub.com/prometheus/client_golang v1.7.0 // indirect\n\tgithub.com/prometheus/client_model v0.2.0 // indirect\n\tgithub.com/prometheus/common v0.10.0 // indirect\n\tgithub.com/prometheus/procfs v0.1.3 // indirect\n\tgithub.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect\n\tgolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect\n\tgolang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect\n\tgolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 // indirect\n\tgolang.org/x/text v0.3.0 // indirect\n\tgoogle.golang.org/protobuf v1.23.0 // indirect\n\tgopkg.in/yaml.v2 v2.2.8 // indirect\n)\n\n```\n\n\n\n**还有一个go sum文件**\n\n\n\n\n\n### 远程推送到github上\n\n1. 在github上新建一个项目Go-mod\n2. `go mod init github.com/3293172751/go-mod`\n3. 添加readme.m\n\n\n\n\n\n## ⚡ go workspace\n\n\n\n## Why you need it？\n\n::: tip\n在参与sealos工程的时候，它们用到了Go语言新特性：Workspaces\n\n+ [https://github.com/labring/sealos/blob/main/DEVELOPGUIDE.md](https://github.com/labring/sealos/blob/main/DEVELOPGUIDE.md)\n\n由于sealos使用的是go1.18的workspace特性，添加新模块后，需要`go work usr -r .`在root目录下运行更新同步的workspace。\n\n我们这篇来学习和使用这个新特性\n\n:::\n\n\n\nGo 多模块工作区能够使开发者能够更容易地同时处理多个模块的工作，如:\n\n\u003e 方便进行依赖的代码调试(打断点、修改代码)、排查依赖代码 bug\n\u003e 方便同时进行多个仓库/模块并行开发调试\n\n\n\n## 简单上手\n\n当前目录结构\n\n![image-20221120151919161](http://sm.nsddd.top/smimage-20221120151919161.png)\n\n\n\n### 文件内容\n\n**mod包内容：**\n\n```go\nmodule nsddd.top/mszlu-common\n\ngo 1.19\n\n-----------\n\nmodule nsddd.top/fly-fish\n\ngo 1.19\n```\n\n\n\n**对应文件：**\n\n`mszlu-common/utils.go`\n\n```go\npackage utils\n\nimport (\n\t\"fmt\"\n)\n\nfunc Print() {\n\tfmt.Println(\"这是utils.go\")\n\n\t//调用fly-fish的main.go\n \n}\n\n```\n\n\n\n`fly-fish/main.go`\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"这是fly-fish的main.go\")\n}\n\n```\n\n\n\n### 如何调用\n\n我们希望调用另一个 mod 模块的函数，我们使用work\n\n```bash\ngo work init ./fly-fish\n```\n\n**使用`fly-fish`**\n\n\n\n我们再加入一个工作区：\n\n```bash\ngo work use ./mszlu-common\n```\n\n\n\n**此时工作目录文件：`go.work`**\n\n```go\ngo 1.19\n\nuse (\n\t./fly-fish\n\t./mszlu-common\n)\n```\n\n\n\n### 调用 utils\n\n`fly-fish/main.go`\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tutils \"nsddd.top/mszlu-common\"\n)\n\nfunc main() {\n\tfmt.Println(\"这是fly-fish的main.go\")\n\tutils.Print()\n}\n\n```\n\n🚀 编译结果如下：\n\n```bash\n[Running] go run \"c:\\Users\\smile\\Desktop\\test\\fly-fish\\main.go\"\n这是fly-fish的main.go\n这是utils.go\n```\n\n\n\n\n\n\n\n## `go work` 支持命令\n\n+ 通常情况下，建议不要提交 **go.work** 文件到 git 上，因为它主要用于本地代码开发。\n+ 推荐在: `$GOPATH` 路径下执行，生成 **go.work** 文件\n+ `go work init` 初始化工作区文件，用于生成 **go.work** 工作区文件\n\n\u003e 初始化并写入一个新的 **go.work** 到当前路径下，可以指定需要添加的代码模块\n\u003e 示例: `go work init ./hello` 将本地仓库 **hello** 添加到工作区\n\u003e **hello** 仓库必须是 go mod 依赖管理的仓库(**./hello/go.mod** 文件必须存在)\n\n+ `go work use` 添加新的模块到工作区\n\n\u003e 命令示例:\n\u003e `go work use ./example` 添加一个模块到工作区\n\u003e `go work use ./example ./example1` 添加多个模块到工作区\n\u003e `go work use -r ./example` 递归 **./example** 目录到当前工作区\n\u003e 删除命令使用 `go work edit -dropuse=./example` 功能\n\n+ `go work edit` 用于编辑 **go.work** 文件\n\n\u003e 可以使用 `edit` 命令编辑和手动编辑 `go.work` 文件效果是相同的 示例:\n\u003e `go work edit -fmt go.work` 重新格式化 **go.work** 文件\n\u003e `go work edit -replace=github.com/link1st/example=./example go.work` 替换代码模块\n\u003e `go work edit -dropreplace=github.com/link1st/example` 删除替换代码模块\n\u003e `go work edit -use=./example go.work` 添加新的模块到工作区\n\u003e `go work edit -dropuse=./example go.work` 从工作区中删除模块\n\n+ `go work sync` 将工作区的构建列表同步到工作区的模块\n+ `go env GOWORK`\n\n\u003e 查看环境变量，查看当前工作区文件路径 可以排查工作区文件是否设置正确，**go.work** 路径找不到可以使用 GOWORK 指定\n\n```\n\u003e go env GOWORK\n$GOPATH/src/link1st/link1st/workspaces/go.work\n```\n\n\n\n### **go.work** 文件结构\n\n+ 文件结构和 **go.mod** 文件结构类似，支持 Go 版本号、指定工作区和需要替换的仓库\n+ 文件结构示例:\n\n```\ngo 1.18\n\nuse (\n    ./hello\n    ./example\n)\n\nreplace (\n    github.com/link1st/example =\u003e ./example1\n)\n```\n\n#### `use` 指定使用的模块目录\n\n+ 可以使用 `go work use hello` 添加模块，也可以手动修改 **go.work** 工作区添加新的模块\n+ 在工作区中添加了模块路径，编译的时候会自动使用 **use** 中的本地代码进行代码编译，和 `replaces` 功能类似。\n\n```\n# 单模块结构\nuse ./hello\n\n# 多模块结构\nuse (\n    ./hello\n    ./example\n)\n```\n\n#### `replaces` 替换依赖仓库地址\n\n+ `replaces` 命令与 **go.mod** 指令相同，用于替换项目中依赖的仓库地址\n+ 需要注意的是 `replaces` 和 `use` 不能同时指定相同的本地路径\n\n\u003e 同时指定报错信息:\n\u003e 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.\n\n+ 错误示例\n\n\u003e 同时在 `use` 和 `replace` 指定相同的本地路径\n\n```\ngo 1.18\n\nuse (\n    ./hello\n    ./example\n)\n\nreplace (\n    github.com/link1st/example =\u003e ./example\n)\n```\n\n#### **go.work** 文件优先级高于 **go.mod** 中定义\n\n+ 在同时使用 **go.work** 和 **go.mod** `replace` 功能的的时候分别指定不同的代码仓库路径，**go.work** 优先级高于 **go.mod** 中定义\n\n\u003e **go.mod** 中定义替换为本地仓库 **example**\n\n```\nreplace (\n    github.com/link1st/example =\u003e ./example1\n)\n```\n\n\u003e **go.work** 中定义替换为本地仓库 **example1**\n\n```\nreplace (\n    github.com/link1st/example =\u003e ./example1\n)\n```\n\n+ 在代码构建时候使用的是 **go.work** 指定的 **example1** 仓库的代码，**go.work** 优先级别更高\n\n### 如何使用\n\n+ 在 Go 1.18 `go run` 和 `go build` 都会默认使用工作区功能\n+ `GOWORK` 也可以指定配置 **go.work** 文件位置\n\n```\nexport GOWORK=\"~/go/src/test/go.18/workspace/go.work\"\n```\n\n### 如何禁用工作区\n\n+ Go 全局变量 `GOWORK` 设置 `off` 则可以禁用工作区功能\n\n\u003e ```\n\u003e export GOWORK=off\n\u003e ```\n\n## 开发流程演示\n\n+ 演示如何使用多模块工作区功能。在现在微服务盛行的年代，一个人会维护多个代码仓库，很多的时候是多个仓库进行同时开发\n+ 假设我们现在进行 **hello** 仓库开发，实现的功能是，实现将输入的字符串反转并输出，字符串反转功能依赖于 **github.com/link1st/example** (下文统称 **example**)公共仓库实现\n+ 新建 **hello** 项目\n\n```\nmkdir hello\ncd hello\n# 代码仓库启动 go mod 依赖管理，生成 go.mod 文件\ngo mod init github.com/link1st/link1st/workspaces/hello\n# 下载依赖包\ngo get github.com/link1st/example\n# 编写 main 文件\nvim main.go\n```\n\n+ **main.go** 代码\n\n```\n// Package main main 文件，go 多模块工作区演示代码\n// 实现将输入的字符串反转输出并输出\npackage main\n\nimport (\n    \"flag\"\n    \"fmt\"\n\n    \"github.com/link1st/example/stringutil\"\n)\n\nvar (\n    str = \"\"\n)\n\nfunc init() {\n    flag.StringVar(\u0026str, \"str\", str, \"输入字符\")\n    flag.Parse()\n}\n\nfunc main() {\n    if str == \"\" {\n        fmt.Println(\"示例: go run main.go -str hello\")\n        fmt.Println(\"str 参数必填\")\n        flag.Usage()\n        return\n    }\n\n    // 调用公共仓库，进行字符串反转\n    str = stringutil.Reversal(str)\n    // 输出反转后的字符串\n    fmt.Println(str)\n    return\n}\n```\n\n+ 运行代码 `go run main.go -str \"hello world\"` 或 `go run github.com/link1st/link1st/workspaces/hello -str \"hello world\"` 可以看到输出了 **hello world** 反转以后的字符串\n\n```\n\u003e go run main.go -str \"hello world\"\ndlrow olleh\n```\n\n+ 到这里，最初的功能已经完成，但是后续需求变动，不仅需要输出反转以后的字符串，还需要将字符串大写\n+ 我们则需要去 **example** 仓库中添加开发 **将字符串大写的功能**\n\n```\n# 回到工作根目录，将 common 代码下载到本地进行添加新的功能\n# 下载依赖的 example 包\ngit clone git@github.com:link1st/example.git\n# 在 example 包中添加 字符串大学的功能\n```\n\n+ **vim example/stringutil/to_upper.go** 代码如下\n\n```\n// Package stringutil stringutil\npackage stringutil\n\nimport (\n    \"unicode\"\n)\n\n// ToUpper 将字符串进行大写\nfunc ToUpper(s string) string {\n    r := []rune(s)\n    for i := range r {\n        r[i] = unicode.ToUpper(r[i])\n    }\n    return string(r)\n}\n```\n\n+ 由于代码还在本地调试，未提交 git 仓库中，这个时候就需要用到 Go 多模块工作区的功能了。\n+ 进入项目根目录，初始化我们现在正在开发的模块\n\n```\n# 初始化 go.work 文件\ngo work init  ./hello ./example\n# 查看 go.work 文件内容\ncat go.work\n```\n\n+ 文件结构如下\n\n```\ngo 1.18\n\nuse (\n    ./example\n    ./hello\n)\n```\n\n+ 回到 **hello** 项目，`vim main.go` 将字符串大写的功能添加上。\n\n```\nfunc main() {\n    ...\n\n    // 调用公共仓库，进行字符串反转\n    str = stringutil.Reversal(str)\n    // 增加字符大写的功能\n    str = stringutil.ToUpper(str)\n    // 输出反转后的字符串\n    fmt.Println(str)\n    \n    ...\n}\n```\n\n+ 运行代码\n\n\u003e 可以看到输出了反转并 **大写** 的字符串，大写的函数功能只在本地，未提交到 git 上，这样我们就实现了可以同时在两个模块上并行开发\n\n```\ngo run main.go -str \"hello world\"\nDLROW OLLEH\n```\n\n+ 到这里，演示的代码已经全部完成\n\n## 总结\n\n+ 使用 Go 多模块工作区的功能，可以让我们轻松在多个模块之间切换工作，更能适应现代微服务架构开发。\n\n\n\n## 参考文献\n\n[Go 1.18 新特性多模块工作区教程](https://github.com/link1st/link1st/tree/master/workspaces)\n\n[Go 1.18 is released!](https://go.dev/blog/go1.18)\n\n[Tutorial: Getting started with multi-module workspaces](https://go.dev/doc/tutorial/workspaces)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcubxxw%2Fgo-mod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcubxxw%2Fgo-mod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcubxxw%2Fgo-mod/lists"}