<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>二七九九笔记</title><link>https://2799.top/</link><description>Good Luck To You!</description><item><title>golang学习路线总结</title><link>https://2799.top/2026/04/11.html</link><description>&lt;h2&gt;基础篇&lt;/h2&gt;&lt;p&gt;go&amp;nbsp;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;提升篇&lt;br/&gt;&lt;/h2&gt;&lt;h2&gt;应用篇&lt;/h2&gt;</description><pubDate>Tue, 14 Apr 2026 18:30:52 +0800</pubDate></item><item><title>Golang Package 与 Module 简介</title><link>https://2799.top/2026/03/10.html</link><description>&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;软件是由代码组成的。为了复用代码，代码的组织出现了不同层次的抽象和实现，如 Module（模块），包（Package），Lib（库），Framwork（框架）等。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;通常一个Project（项目），会根据功能拆分很多 module，常用的软件会打包成一个个共享库。在开源社区分享软件包是一件十分 cool 的事儿。这些软件包也有可能引用了其他的开源包，因此开源项目上经常会有软件相互依赖，或依赖某个包，或依赖某个包的某个版本。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;现代的语言都有很多好用的包管理工具，如 pip 之于 python，gem 之于 ruby，npm 之于 nodejs。然而 Golang 早期版本却没有官方的包管理器，直到 go1.5 才添加了实验性的 vendor。尽管官方的不作为（保守），还是无法阻止社区的繁荣。社区诞生了许多工具，比较有代表如 govender，glide，gopm，以及半官方的 dep 等。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;百花齐放的另外一层含义也是工具链混乱的表现。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;终于在 go1.12，发布了官方的包管理工具 Go Module。go module 不仅带来了统一的标准，而且对于旧软件包的处理，以及所坚持的包管理哲学都挺有意思。下面将会从 go module 之前的包管理方式和升级到 go module 方式做一个简单的说明。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;下面的例子以常见的使用方式做介绍，并没有深入其背后的原理与实现。例如go.sum 以及一些最下化处理原则不会涉及。部分内容闲扯一下 go 的流派观点。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;GOPATH&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;在 go1.12 之前，安装 golang 之后，需要配置两个环境变量----GOROOT 和GOPATH。前者是 go 安装后的所在的路径，后者是开发中自己配置的，用于存放go 源代码的地方。在 GOPATH 路径内，有三个文件夹，分别是&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;bin: go 编译后的可执行文件所在的文件夹&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;pkg: 编译非 main 包的中间连接文件&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;src: go 项目源代码&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;开发的程序源码则放在src里，可以在src里创建多个项目。每一个项目同时也是一个文件夹。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;go1.12 之后，淡化了 GOPATH，因此也可以忽略这部分内容。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;Package&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;main package&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;golang 的所有文件都需要指定其所在的包（package），包有两种类型，一种是 main 包，使用 package main 在代码的最前面声明。另外一种就是 非main 包，使用 package + 包名 。main 包的可以有唯一的一个 main 函数，这个函数也是程序的入口。也只有 main 包可以编译成可执行的文件。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;下面看一个简单的例子：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;golang&amp;nbsp;echo&amp;nbsp;$GOPATH/Users/master/golang
➜&amp;nbsp;golang&amp;nbsp;pwd/Users/master/golang
➜&amp;nbsp;golang&amp;nbsp;tree
.
├──&amp;nbsp;bin
├──&amp;nbsp;pkg
└──&amp;nbsp;src
└──&amp;nbsp;demo
└──&amp;nbsp;main.go&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;4 directories, 1 file&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;main.go
package&amp;nbsp;main

import&amp;nbsp;(&amp;quot;fmt&amp;quot;)

func&amp;nbsp;main()&amp;nbsp;{fmt.Println(&amp;quot;hello&amp;nbsp;world&amp;quot;)
}

➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
hello&amp;nbsp;world&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;从上面的目录结构可以看出，GOPATH为 /Users/master/golang 。在 src 内创建了一个项目 demo。demo 里有一个 main.go 文件。main.go 的第一行声明了这是一个 main 包，因此可以定义一个 main 函数。使用 go run 可以编译并运行 main.go。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;虽然 main 包的文件名也是 main.go，其实包名和文件名没有直接关系。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;自定义 package&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;go 使用 package 来管理源文件。package 必须在一个文件夹内，且一个文件夹内也只能有一个package，但是一个文件夹可以有多个文件。下面自定义一个 package。&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;&lt;span style=&quot;margin: 0px; padding: 0px; font-size: inherit; line-height: 1.5;&quot;&gt;➜ demo tree
.
├── main.go
└── service
└── http.go&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px;&quot;&gt;1 directory, 2 files&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;➜ demo cat service/http.go&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;package api&lt;/p&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;&lt;br/&gt;&lt;/pre&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px;&quot;&gt;import &amp;quot;fmt&amp;quot;&lt;/p&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;&lt;br/&gt;&lt;/pre&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px;&quot;&gt;func HandleReq(){&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;fmt.Println(&amp;quot;api - http.go Handle Request&amp;quot;)&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;}&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;➜ demo cat main.go&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;package main&lt;/p&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;&lt;br/&gt;&lt;/pre&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px;&quot;&gt;import (&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&amp;quot;fmt&amp;quot;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&amp;quot;./service&amp;quot;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;)&lt;/p&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;&lt;br/&gt;&lt;/pre&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px;&quot;&gt;func main() {&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;fmt.Println(&amp;quot;hello world&amp;quot;)&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;api.HandleReq()&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;}&lt;/p&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;&amp;nbsp;&lt;br/&gt;&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;在 demo 文件内创建一个文件夹 service，在 service 内又创建了 http.go 文件。后者声明为 package api ，即包名为 api。然后在 main.go 文件中，通过 import &amp;quot;./service&amp;quot; 引入了api 包所在的文件夹。最后通过 包名.包函数 调用。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;输出结果如下：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
hello&amp;nbsp;world
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;从上面的例子可以看到，包名为 api，文件夹为 service，文件为 http.go。它们三者的命名都是不一样的。这与很多其他语言相悖。正如前文所言，一个包可以分散在不同的同级文件里，只要都声明为一个包名即可。例如下面再增加一个文件：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;service/rpc.go
package&amp;nbsp;api

import&amp;nbsp;&amp;quot;fmt&amp;quot;func&amp;nbsp;HandleResp(){fmt.Println(&amp;quot;api&amp;nbsp;-&amp;nbsp;rpc.go&amp;nbsp;Handle&amp;nbsp;Request&amp;quot;)
}&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;在 main 函数里同样使用 包名.包函数 ---- api.HandleResp() 调用。其实很好理解，即同样的一个包，文件内容太多，拆分成多个文件而已。文件名跟包名没有直接关系。如果只有一个文件，通常可以写成包名。但是导入的时候，必须导入包所在的文件夹的路径。其实可以这样理解，import 的是 path（路径），那么go就去那个路径下搜索，搜索当然是查找包名。只不过通常习惯是 文件名 和 包名一致。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;这包名和文件夹名不一致，是反模式。主要是为了直观的表示包名和文件夹名没有直接关系。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;内嵌 package&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;在 service 内再创建一个文件夹 api，此时再命名一个 api.go 文件。即 文件夹名 和 包名 一致。其内容如下：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;service/api/api.go
package&amp;nbsp;api

import&amp;nbsp;&amp;quot;fmt&amp;quot;func&amp;nbsp;HandleError(){fmt.Println(&amp;quot;api&amp;nbsp;api.go&amp;nbsp;Handle&amp;nbsp;Error&amp;quot;)
}&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;import package 就是导入包所在的文件夹，因此 main.go 如下：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;import&amp;nbsp;(&amp;quot;fmt&amp;quot;&amp;quot;./service&amp;quot;&amp;quot;./service/api&amp;quot;)&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;但是这样编译会报错：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
#&amp;nbsp;command-line-arguments
./main.go:6:9:&amp;nbsp;api&amp;nbsp;redeclared&amp;nbsp;as&amp;nbsp;imported&amp;nbsp;package&amp;nbsp;name
previous&amp;nbsp;declaration&amp;nbsp;at&amp;nbsp;./main.go:5:2./main.go:11:2:&amp;nbsp;undefined:&amp;nbsp;&amp;quot;_/Users/master/golang/src/demo/service/api&amp;quot;.HandleReq
./main.go:12:9:&amp;nbsp;undefined:&amp;nbsp;&amp;quot;_/Users/master/golang/src/demo/service/api&amp;quot;.HandleResp&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;显然，在 service 文件内的 http.go 和 rpc.go 声明了 package api。在 service/api 文件夹里的 api.go 也声明为 api。这是同名的两个包。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;但是在 main 函数里，都是使用包名引用函数。由于名字冲突，无法确定到底使用那个 api 包，进而报错。解决方法也很简单，给包名增加一个别名即可。&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;import&amp;nbsp;(&amp;quot;fmt&amp;quot;&amp;quot;./service&amp;quot;apiNew&amp;nbsp;&amp;quot;./service/api&amp;quot;)

func&amp;nbsp;main()&amp;nbsp;{fmt.Println(&amp;quot;hello&amp;nbsp;world&amp;quot;)
api.HandleReq()
api.HandleResp()
apiNew.HandleError()
}&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;这样 api 就是 service 空间下的，apiNew 就是 service/api 空间下，两者相互隔离。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;导入规则&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;前面 import 语句内，通过相对路径导入了包。对于*nix系统，相对路径 . 通常是可以省略的。下面就省略试试：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;import&amp;nbsp;(&amp;quot;fmt&amp;quot;&amp;quot;service&amp;quot;apiNew&amp;nbsp;&amp;quot;service/api&amp;quot;)&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;此时会发现报错：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
main.go:5:2:&amp;nbsp;cannot&amp;nbsp;find&amp;nbsp;package&amp;nbsp;&amp;quot;service&amp;quot;&amp;nbsp;in&amp;nbsp;any&amp;nbsp;of:/usr/local/go/src/service&amp;nbsp;(from&amp;nbsp;$GOROOT)/Users/master/golang/src/service&amp;nbsp;(from&amp;nbsp;$GOPATH)
main.go:6:9:&amp;nbsp;cannot&amp;nbsp;find&amp;nbsp;package&amp;nbsp;&amp;quot;service/api&amp;quot;&amp;nbsp;in&amp;nbsp;any&amp;nbsp;of:/usr/local/go/src/service/api&amp;nbsp;(from&amp;nbsp;$GOROOT)/Users/master/golang/src/service/api&amp;nbsp;(from&amp;nbsp;$GOPATH)&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;报错信息也简单明了。即 go 先从 $GOROOT/src 搜索 service 包，找不到然后从 $GOPATH/src 里搜索。也找不到，进而报错。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;这里就涉及到 go 的包搜索方式。通常 standard pkg（标准库）都在$GOROOT/src 里，因此会从这里搜索。而用户自定义的包，或者三方包，go是统一从 $GOPATH/src 里搜索的。当不使用 . 显式表明相对导入，那么 go 就会相对于 $GOPATH/src 导入。解决上面的方法就是把 service 包放到 demo 外面&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;src&amp;nbsp;tree
.
├──&amp;nbsp;demo
│&amp;nbsp;├──&amp;nbsp;main.go
│&amp;nbsp;└──&amp;nbsp;service
│&amp;nbsp;├──&amp;nbsp;api
│&amp;nbsp;│&amp;nbsp;└──&amp;nbsp;api.go
│&amp;nbsp;├──&amp;nbsp;http.go
│&amp;nbsp;└──&amp;nbsp;rpc.go
└──&amp;nbsp;service
├──&amp;nbsp;api
│&amp;nbsp;└──&amp;nbsp;api.go
├──&amp;nbsp;http.go
└──&amp;nbsp;rpc.go5&amp;nbsp;directories,&amp;nbsp;7&amp;nbsp;files&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;通常，如果 service 是 demo 的一个内部模块，那么就放到 demo 内，使用 . 方式相对导入。如果它是一个可以共享的 package，就可以放到 GOPATH 下。为什么 go会使用 GOPATH 这样的集中文件夹呢？&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;此外，想要把这个 service 包发布出去，可以使用 github 管理源代码和包版本。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;首先需要从 github 创建一个 repo（仓库）。常见的形式是 github.com/username/repo。因此软件包的名也是这个规则。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;例子：&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;初始化 service&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;在 github上创建一个 repo 叫 service， 并打上了 v1.0.0 的版本 tag。那么在mian.go 里引用就是这样：&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;import&amp;nbsp;(&amp;quot;fmt&amp;quot;&amp;quot;github.com/rsj217/service&amp;quot;)&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;上述的 import 语句，无非就是增加了包 servic e的文件夹层级 github.com/rsj217 而已。这样做的主要目的是为了让 go get 工具从网络上的 url 地址拉取包。go get 会自动从 github.com/rsj217/service 拉取源码，并 copy 到 $GOPATH/src 下。运行go get 或者 go run main.go ，go 都会从 import 语句中解析并下载软件包。&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;get&amp;nbsp;github.com/rsj217/service
➜&amp;nbsp;demo&amp;nbsp;tree&amp;nbsp;../../├──&amp;nbsp;demo
│&amp;nbsp;└──&amp;nbsp;main.go
└──&amp;nbsp;github.com
└──&amp;nbsp;rsj217
└──&amp;nbsp;service
├──&amp;nbsp;LICENSE
├──&amp;nbsp;README.md
├──&amp;nbsp;api
│&amp;nbsp;└──&amp;nbsp;api.go
├──&amp;nbsp;http.go
└──&amp;nbsp;rpc.go5&amp;nbsp;directories,&amp;nbsp;6&amp;nbsp;files&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;从前面包的搜索方式就很容易理解。import &amp;quot;github.com/rsj217/service&amp;quot; go 就从 $GOPATH/src 下搜索，正好能搜索到 github.com/rsj217/service。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;进入到 service文件夹内，可以看到就是完整的 git repo 的clone。修改提交后，即使删掉这个包。再使用 go get 也能再次下载。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;Why GOPATH&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;前面我们抛了一个问题： 为什么 go 会使用 GOPATH 这样的集中文件夹呢？go 不像 python 有一个中央仓库 PyPI 用来管理存储软件包，以提供给包管理工具 pip 下载。而 python 也不像 go 那样有个本地的 GOPATH 用来搜索软件包。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;对于 python 开发者而言，源码怎么管理都无所谓。但是只要想分发软件包，就可以打包然后传到 pypi 即可。想要使用软件包，从 pypi 搜索即可（或从github.com）。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;但是go是另外一种开发方式。从一些朋友了解到Google的开发方式。他们本身就有一个中央集中式中心用来管理软件包。使用，构建都从那里获取。因为外人无法访问google的中央，但是这种引用中央的开发模式被保留下来，因此就抽象成本地的GOPATH。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;至于软件的分发，就从源代码拉取即可。有名的源代码版本管理无非就是 github 之类。google的做法就是让用户自己维护一个在本地类似 pypi 的中央库。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;自己怎么维护呢？就是通过 go get 从 github 或者其他类似的网站上获取，然后打包，处理依赖。这样的一个好处就是自己把分散式的 github 开源包进行了本地的集中式处理。处理依赖的时候会比较方便，毕竟本地什么东西都有了。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;但是从上面的 case 可以看出，go get 就类似 git clone。即使每次 go get 拉取仓库都是最新的版本。如何处理好版本依赖呢？&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;在go module之前也有不少解决方案，但是都或多或少有优劣。下面就介绍一下 go module 的使用方式。&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;go&amp;nbsp;module

go1.12&amp;nbsp;引入了&amp;nbsp;go&amp;nbsp;Module，即&amp;nbsp;go&amp;nbsp;的软件包都可以声明为&amp;nbsp;module。同时淡化了GOPATH，之所以说淡化，是因为即使使用1.12版本，用户不用配置GOPATH环境变量，但是它还是以另外一种形式存在。

go1.12&amp;nbsp;会在用户的&amp;nbsp;$home&amp;nbsp;目录下创建一个&amp;nbsp;go&amp;nbsp;文件夹作为默认的&amp;nbsp;GOPATH。

➜&amp;nbsp;~&amp;nbsp;echo&amp;nbsp;$GOPATH

➜&amp;nbsp;~&amp;nbsp;go&amp;nbsp;env&amp;nbsp;|&amp;nbsp;grep&amp;nbsp;GOPATH
GOPATH=&amp;quot;/Users/master/go&amp;quot;&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;虽然引入了 module，但是并没有废弃 go get，go get 还是基于 GOPATH 运作的，并且 go 的开发方式也没有放弃。只是减少了用户的心智负担，但也提升了用户体验。go get 会将远程的软件包 download 在 $home/go/pkg/mod 目录里。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;没有了显示的 GOPATH，开发者的项目就不用像之前一样放到 GOPATH/src 下面了。用户可以在任何一个文件创建自己的项目。下面是一个例子:&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;随意创建一个 demo 文件夹作为项目。使用 mod 命令 声明一个 module。然后编写 main.go&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;mod&amp;nbsp;init&amp;nbsp;demo
go:&amp;nbsp;creating&amp;nbsp;new&amp;nbsp;go.mod:&amp;nbsp;module&amp;nbsp;demo
➜&amp;nbsp;demo&amp;nbsp;lsgo.mod
➜&amp;nbsp;demo&amp;nbsp;echo&amp;nbsp;$GOPATH

➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;go.mod
module&amp;nbsp;demo

go&amp;nbsp;1.12➜&amp;nbsp;demo&amp;nbsp;tree
.
├──&amp;nbsp;go.mod
└──&amp;nbsp;main.go0&amp;nbsp;directories,&amp;nbsp;2&amp;nbsp;files
➜&amp;nbsp;demo&amp;nbsp;less&amp;nbsp;main.go

package&amp;nbsp;main

import&amp;nbsp;(&amp;quot;fmt&amp;quot;//&amp;nbsp;&amp;quot;github.com/rsj217/service&amp;quot;)

func&amp;nbsp;main()&amp;nbsp;{fmt.Println(&amp;quot;hello&amp;nbsp;world&amp;quot;)//&amp;nbsp;api.HandleReq()//&amp;nbsp;api.HandleResp()}&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;go mod init 会在当前文件夹下创建一个 go.mod 文件，里面声明了当前 module 的名字。以后也可以把相关依赖写在这个文件里，就像 python 的 requirements.txt 文件一样。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;编译运行 main.go，会发现项目即使没有 $GOPATH/src 下，也能正常运行。下面把上面的main.go 的注释去掉。再次编译运行&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
go:&amp;nbsp;finding&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.0.0go:&amp;nbsp;downloading&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.0.0go:&amp;nbsp;extracting&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.0.0hello&amp;nbsp;world
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
api&amp;nbsp;--&amp;nbsp;rpc.go&amp;nbsp;Handle&amp;nbsp;Response
➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;go.mod
module&amp;nbsp;demo

go&amp;nbsp;1.12require&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.0.0&amp;nbsp;//&amp;nbsp;indirect➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;list&amp;nbsp;-m&amp;nbsp;all
demo
github.com/rsj217/service&amp;nbsp;v1.0.0&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;go 会检测 main.go 里的 import 语句。并尝试根据 go.mod 的依赖引用关系导入三方包。如果发现本地cache没有，就会从远程拉取。就像是 go get。当 go module下载了远程包后，同时会自动更新 go.mod 。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;如上面就追加了 require github.com/rsj217/service v1.0.0 // indirect 这样一句。require 指令后跟软件包名和版本号。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;对于 demo，其包名为 module demo 里声明的 demo，对于 service，当前不是一个 module，因此其包名是 github.com/rsj217/service。版本号就是 repo 的 tag。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;软件包被缓存在 $home/go/pkg/mod 目录里， mod 目录就像之前的 src 一样。里面也有 github.com 目录。最终可以看到在 github.com/rsj217/ 文件下有 service@v1.0.0文件夹，里面正好就是之前 service 的代码&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;service@v1.0.0&amp;nbsp;pwd/Users/master/go/pkg/mod/github.com/rsj217/service@v1.0.0➜&amp;nbsp;service@v1.0.0&amp;nbsp;tree
.
├──&amp;nbsp;LICENSE
├──&amp;nbsp;README.md
├──&amp;nbsp;api
│&amp;nbsp;└──&amp;nbsp;api.go
├──&amp;nbsp;http.go
└──&amp;nbsp;rpc.go1&amp;nbsp;directory,&amp;nbsp;5&amp;nbsp;files&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;service@v1.0.0 与之前的 go get clone 的service 项目不一样。前者只下载了版本号为 1.0.0 的仓库（如果没有打tag，就是指定的某个commit），而后者是整个 repo 的clone。由此可见，go module 是可以精确的拉取目标版本。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;语义化版本&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;go module 同时引入了 semver (Semantic Versioning)。它定义的版本号格式是：&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;vMAJOR.MINOR.PATCH&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;v：表示版本&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;MAJOR：主版本，通常是大版本升级，导致向前不兼容&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;MINOR：次版本，通常是向下兼容的 feture&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;PATCH：修订版本，如一些bugfix。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;下面针对刚才的 service@v1.0.0 升级到1.1.0 版本。通过 git 修改 http.go，然后push一个v1.1.0 的 tag。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;v1.0.0&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;然后使用 go get -u 升级版本&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;get&amp;nbsp;-u
go:&amp;nbsp;finding&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.1.0go:&amp;nbsp;downloading&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.1.0go:&amp;nbsp;extracting&amp;nbsp;github.com/rsj217/service&amp;nbsp;v1.1.0&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;要升级或降级到更具体的版本，go get 允许通过在 包参数中添加 @version 后缀搜索。如 go get service@v1.0.0，go get service@dsa1ewr，或者 go get service@&amp;lt;v1.3.2。&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;使用 go get -u 会把所依赖的次级包也跟着升级，原因参考golang modules问题的理解与踩坑记&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;)，不是特别友好。比较好的方式是指定版本的具体包或者修改 go.mod 文件。这里没有次级依赖，为了方便，下面的更新也使用了 go get -u&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;可以看到，mod 里多了一个 service@v1.2.0 的文件夹包，go.mod 也引用了 v1.2.0的软件。运行main.go ，也输出了 1.1.0 升级后的内容。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;大版本升级&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;升级 MINOR 和 PATCH 都比较简单，升级 MAJOR 稍微复杂一点点。再次修改service 仓库，然后打一个 V2.1.0 的tag。推送到远程分支。再使用go get -u 升级&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;get&amp;nbsp;-u
go:&amp;nbsp;downloading&amp;nbsp;github.com/rsj217/service&amp;nbsp;v2.1.0+incompatible
go:&amp;nbsp;extracting&amp;nbsp;github.com/rsj217/service&amp;nbsp;v2.1.0+incompatible
➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;list&amp;nbsp;-m&amp;nbsp;all
demo
github.com/rsj217/service&amp;nbsp;v2.1.0+incompatible
➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;go.mod
module&amp;nbsp;demo

go&amp;nbsp;1.12require&amp;nbsp;github.com/rsj217/service&amp;nbsp;v2.1.0+incompatible

➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
hello&amp;nbsp;world
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
v2.1.0api&amp;nbsp;--&amp;nbsp;rpc.go&amp;nbsp;Handle&amp;nbsp;Response&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;可以看到，在下载软件包的时候，版本号跟着有一个 incompatible 标记 。incompatible 表示是大版本升级，与之前的版本可能不兼容。但是运行main.go的时候，依然可以正确的找到 2.1.0的版本。并且 $home/go 里的软件包也多了一个 service@v2.1.0+incompatible。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;旧包升级到 go module&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;本地的项目 demo 已经使用了 go module 声明，对于其依赖 service，也可以改造成 go module，只需要增加一个 go.mod 文件即可。然后打上一个 v2.2.0的 tag。当然 修改 http.go ，以便测试是 v2.2.0 的内容。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;然后更新下载依赖&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;get&amp;nbsp;github.com/rsj217/service@v2.2.0go:&amp;nbsp;finding&amp;nbsp;github.com/rsj217/service&amp;nbsp;v2.2.0go:&amp;nbsp;downloading&amp;nbsp;github.com/rsj217/service&amp;nbsp;v0.0.0-20190508051156-b9ee113ae63e
go:&amp;nbsp;extracting&amp;nbsp;github.com/rsj217/service&amp;nbsp;v0.0.0-20190508051156-b9ee113ae63e&lt;/pre&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;从上面的输出可以看到，因为已经有了v2的版本，就应该在声明 module 的时候加上v2。如果不加，那么go貌似认为 tag 没有打上。不管怎么样，代码库还是下载了。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;查看本地的包会发现有之前的好几个版本，其中 v2.2.0 的被命名为 service@v0.0.0-20190508051156-b9ee113ae63e 。因为刚初始化的 module 认为没有打上 tag，对于没有打 tag 的，go.mod 的格式是 pseudo-version。它的含义是v0.0.0-yyyymmddhhmmss-abcdefabcdef&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;查看所下载的软包&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;rsj217&amp;nbsp;lsservice@v0.0.0-20190508051156-b9ee113ae63e&amp;nbsp;service@v1.1.0service@v1.0.0&amp;nbsp;service@v2.1.0+incompatible

➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;go.mod
module&amp;nbsp;demo

go&amp;nbsp;1.12require&amp;nbsp;github.com/rsj217/service&amp;nbsp;v0.0.0-20190508051156-b9ee113ae63e

➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
hello&amp;nbsp;world
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
v2.2.0api&amp;nbsp;--&amp;nbsp;rpc.go&amp;nbsp;Handle&amp;nbsp;Response&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;从go.mod 和运行效果来看，确实升级到 v2.2.0版本的代码库了。只是go module对于大于 v1 的版本库，其声明的 module 也要加上vMAJOR。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;go module 多版本共存&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;上述的 v2.2.0 没有被 go module 识别，是因为 go.mod 的 module github.com/rsj217/service 没有带上 MAJOR 版本号。将 go.mod 改成 module github.com/rsj217/service/v3，即新的 go.mod，然后再打上一个v3.0.0 的版本再更新。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;由于（假设） v3.0.0 与 之前的版本都不兼容，但是demo项目又同时需要两个版本的包，此时就是 go module 比之前 go get 方式优越了。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;正如 v3.0.0 的 go.mod 加上了版本号，因此对于使用者而言，其实可以理解为是不同命名空间包。就像之前 service 下的 api 和 service/api 下的 api 一样。需要用别名区别。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;修改 go.mod 增加两个版本的包。v2.2.0 和 v3.0.0&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;go.mod
module&amp;nbsp;demo

go&amp;nbsp;1.12require&amp;nbsp;(
github.com/rsj217/service&amp;nbsp;v0.0.0-20190508051156-b9ee113ae63e
github.com/rsj217/service/v3&amp;nbsp;v3.0.0)

➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;main.go
package&amp;nbsp;main

import&amp;nbsp;(&amp;quot;fmt&amp;quot;&amp;quot;github.com/rsj217/service&amp;quot;&amp;nbsp;//&amp;nbsp;使用&amp;nbsp;v2.2.0&amp;nbsp;的包apiv3&amp;nbsp;&amp;quot;github.com/rsj217/service/v3&amp;quot;&amp;nbsp;//&amp;nbsp;使用&amp;nbsp;v3.0.0&amp;nbsp;的包)

func&amp;nbsp;main()&amp;nbsp;{fmt.Println(&amp;quot;hello&amp;nbsp;world&amp;quot;)
api.HandleReq()
api.HandleResp()
apiv3.HandleReq()
}


➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
go:&amp;nbsp;downloading&amp;nbsp;github.com/rsj217/service/v3&amp;nbsp;v3.0.0go:&amp;nbsp;extracting&amp;nbsp;github.com/rsj217/service/v3&amp;nbsp;v3.0.0hello&amp;nbsp;world
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
v2.2.0api&amp;nbsp;--&amp;nbsp;rpc.go&amp;nbsp;Handle&amp;nbsp;Response
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
v3.0.0&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;可以看到 main.go 里的 import 语句，显示的区分了 v2 版本和 v3 版本。查看 home/go 下面的目录，会发现多了一个 service 文件夹，里面放了一个 v3 版本的包。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;不管怎样，go module 通过 vMAJOR 让用户可以同时使用多个版本的软件包。但是需要修改使用者的代码，还是略麻烦。不过既然进行了向前不兼容，又得保证旧代码正常work，想来也没有更好的办法。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;本地包&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;开源社区的最大好处就是共享智慧。可是实际开发中，开源的包也未必都十分可靠。通常可以提 PR 提 ISSUE 参与改进。但是原作者要是不维护就得需要自己 fork 修改。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;还有一些涉及到商业方向的代码包，总不能扔到 github 上开源。因此本地构建也是一个需求。例如上面的 v3.0.0 有类似的 bug。可以在本地修改一个版本，然后通过 go module 的 replace 指令替换到 github 上的包。&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;mod&amp;nbsp;vendor
➜&amp;nbsp;demo&amp;nbsp;lsgo.mod&amp;nbsp;go.sum&amp;nbsp;main.go&amp;nbsp;vendor
➜&amp;nbsp;demo&amp;nbsp;cd&amp;nbsp;vendor
➜&amp;nbsp;vendor&amp;nbsp;tree
.
├──&amp;nbsp;github.com
│&amp;nbsp;└──&amp;nbsp;rsj217
│&amp;nbsp;└──&amp;nbsp;service
│&amp;nbsp;├──&amp;nbsp;LICENSE
│&amp;nbsp;├──&amp;nbsp;README.md
│&amp;nbsp;├──&amp;nbsp;go.mod
│&amp;nbsp;├──&amp;nbsp;http.go
│&amp;nbsp;├──&amp;nbsp;rpc.go
│&amp;nbsp;└──&amp;nbsp;v3
│&amp;nbsp;├──&amp;nbsp;LICENSE
│&amp;nbsp;├──&amp;nbsp;README.md
│&amp;nbsp;├──&amp;nbsp;go.mod
│&amp;nbsp;├──&amp;nbsp;http.go
│&amp;nbsp;└──&amp;nbsp;rpc.go
└──&amp;nbsp;modules.txt4&amp;nbsp;directories,&amp;nbsp;11&amp;nbsp;files&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;使用 go vendor，可以将依赖包copy到项目的 vendor文件下。如上面的例子 vendor下的结构和之前的 GOPATH/src home/go 类似。修改 v3 下的 http.go&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;v3&amp;nbsp;cat&amp;nbsp;http.go
package&amp;nbsp;api

import&amp;nbsp;&amp;quot;fmt&amp;quot;func&amp;nbsp;HandleReq(){fmt.Println(&amp;quot;api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request&amp;quot;)fmt.Println(&amp;quot;&amp;nbsp;vendor&amp;nbsp;v3.0.0&amp;quot;)
}&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;然后修改 go.mod ，添加 replace指令&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;cat&amp;nbsp;go.mod
module&amp;nbsp;demo

go&amp;nbsp;1.12require&amp;nbsp;(
github.com/rsj217/service&amp;nbsp;v0.0.0-20190508051156-b9ee113ae63e
github.com/rsj217/service/v3&amp;nbsp;v3.0.0)

replace&amp;nbsp;github.com/rsj217/service/v3&amp;nbsp;v3.0.0&amp;nbsp;=&amp;gt;&amp;nbsp;./vendor/github.com/rsj217/service/v3

➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;run&amp;nbsp;main.go
hello&amp;nbsp;world
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
v2.2.0api&amp;nbsp;--&amp;nbsp;rpc.go&amp;nbsp;Handle&amp;nbsp;Response
api&amp;nbsp;-&amp;nbsp;http.go&amp;nbsp;Handle&amp;nbsp;Request
vendor&amp;nbsp;v3.0.0➜&amp;nbsp;demo&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;从运行结果可以看到，go module找到了本地的 vendor里的版本。如果一开始 service项目就不想开源。声明其module 就可以不加 github.com 。可以直接声明成一个 service module。最好是使用git init 初始化为本地的 repo。然后使用 replace 指令，将 service 包指定到本地某个目录。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;除了针对大版本声明 module 需要 vMARJOR，其他时候，module 的名字是否加 github.com/username 并不是硬性要求，毕竟有 replace 大法。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;依赖关系&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;通过上面从一个普通的 go package 的改造成 go module 的例子。可以看到 go 在包管理工具上的努力。尤其是对不兼容版本的支持，还是有一定防范。但是需要改源文件，还是略显不够优雅。另外，go mod还提供了一些了命令。如 go list 可以看出当前 module 的依赖&lt;/p&gt;&lt;div class=&quot;cnblogs_code&quot; style=&quot;margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); overflow: auto; text-wrap-mode: wrap; font-family: &amp;quot;Courier New&amp;quot; !important; font-size: 12px !important;&quot;&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background, font-size, border-color, border-radius, border-width, padding, margin, color; overflow: auto; font-family: &amp;quot;Courier New&amp;quot;, serif; overflow-wrap: break-word;&quot;&gt;➜&amp;nbsp;demo&amp;nbsp;go&amp;nbsp;list&amp;nbsp;-m&amp;nbsp;-json&amp;nbsp;all
{&amp;quot;Path&amp;quot;:&amp;nbsp;&amp;quot;demo&amp;quot;,&amp;quot;Main&amp;quot;:&amp;nbsp;true,&amp;quot;Dir&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/demo&amp;quot;,&amp;quot;GoMod&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/demo/go.mod&amp;quot;,&amp;quot;GoVersion&amp;quot;:&amp;nbsp;&amp;quot;1.12&amp;quot;}
{&amp;quot;Path&amp;quot;:&amp;nbsp;&amp;quot;github.com/rsj217/service&amp;quot;,&amp;quot;Version&amp;quot;:&amp;nbsp;&amp;quot;v0.0.0-20190508051156-b9ee113ae63e&amp;quot;,&amp;quot;Time&amp;quot;:&amp;nbsp;&amp;quot;2019-05-08T05:11:56Z&amp;quot;,&amp;quot;Dir&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/go/pkg/mod/github.com/rsj217/service@v0.0.0-20190508051156-b9ee113ae63e&amp;quot;,&amp;quot;GoMod&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/go/pkg/mod/cache/download/github.com/rsj217/service/@v/v0.0.0-20190508051156-b9ee113ae63e.mod&amp;quot;,&amp;quot;GoVersion&amp;quot;:&amp;nbsp;&amp;quot;1.12&amp;quot;}
{&amp;quot;Path&amp;quot;:&amp;nbsp;&amp;quot;github.com/rsj217/service/v3&amp;quot;,&amp;quot;Version&amp;quot;:&amp;nbsp;&amp;quot;v3.0.0&amp;quot;,&amp;quot;Replace&amp;quot;:&amp;nbsp;{&amp;quot;Path&amp;quot;:&amp;nbsp;&amp;quot;./vendor/github.com/rsj217/service/v3&amp;quot;,&amp;quot;Dir&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/demo/vendor/github.com/rsj217/service/v3&amp;quot;,&amp;quot;GoVersion&amp;quot;:&amp;nbsp;&amp;quot;1.12&amp;quot;},&amp;quot;Dir&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/demo/vendor/github.com/rsj217/service/v3&amp;quot;,&amp;quot;GoMod&amp;quot;:&amp;nbsp;&amp;quot;/Users/master/demo/vendor/github.com/rsj217/service/v3/go.mod&amp;quot;,&amp;quot;GoVersion&amp;quot;:&amp;nbsp;&amp;quot;1.12&amp;quot;}&lt;/pre&gt;&lt;div class=&quot;cnblogs_code_toolbar&quot; style=&quot;margin: 5px 0px 0px; padding: 0px;&quot;&gt;&lt;span class=&quot;cnblogs_code_copy&quot; style=&quot;margin: 0px; padding: 0px 5px 0px 0px; font-family: &amp;quot;Courier New&amp;quot;, serif; font-size: inherit; line-height: 1.5;&quot;&gt;&lt;a title=&quot;复制代码&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179); text-decoration-line: underline; border: none !important;&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102413177492385395775.gif&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;从上面的 json 可以看出，demo 项目依赖 github.com/rsj217/service 的 &amp;quot;v0.0.0-20190508051156-b9ee113ae63e&amp;quot; 版本，即 git 的（v2.2.0）。还依赖 github.com/rsj217/service/v3 的 v3.0.0 也是 git 的（v3.0.0）&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;总结&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;golang 1.12 正式发布了 go module 特性。go module 作为官方的包管理解决方案。既然针对旧软件包能work，也可以将旧软件包升级为 go module。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;go module 淡化了 GOPATH 的概念。用户不设置 GOPATH，golang会自动在 home/go/pkg/mod 中，并且可以存储多个版本的包。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;为了管理包依赖，go module 引入了 go.mod文件， 通过 module 指令声明一个module，通过 require 指定依赖，通过 replace 替换依赖。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;同时 软件包的版本提供了一个 版本格式 ，并且针对 大于 v1 的软件包，声明的module 也需要加上vMarjor。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;总而言之，go module在不对原有的包管理带来破坏的情况下，引入了新的workflow，只要遵循这些约定，还是可以轻松的解决日常开发的包管理问题。&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;相关连接：&lt;/p&gt;&lt;p style=&quot;margin: 10px auto; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; text-wrap-mode: wrap; background-color: rgb(254, 254, 242);&quot;&gt;&lt;a href=&quot;https://roberto.selbach.dev/intro-to-go-modules/&quot; target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179);&quot;&gt;Introduction to Go Modules&lt;/a&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;a href=&quot;https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16&quot; target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179);&quot;&gt;Anatomy of Modules in Go&lt;/a&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;a href=&quot;https://blog.cyeam.com/go/2019/03/12/go-version&quot; target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179);&quot;&gt;Go module 如何发布 v2 及以上版本？&lt;/a&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;a href=&quot;https://daozhao.goflytoday.com/2019/05/golang-modules/&quot; target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(7, 93, 179);&quot;&gt;golang modules问题的理解与踩坑记&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 31 Mar 2026 10:23:31 +0800</pubDate></item><item><title>【Go】理解包、模块</title><link>https://2799.top/2026/03/9.html</link><description>&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go 作为一门成熟的语言，有着详尽的文档。但官方的入门文档过于简单，而参考手册又过于丰富，让新人觉得无从着手。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;本文由浅入深地解释清楚：&lt;strong style=&quot;box-sizing: inherit&quot;&gt;在Go语言中，包（package）是代码组织和重用的基本单位，而模块（module）是控制版本和管理依赖的单元&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;本文主要受众应该是：有一定Go使用经验，但是在使用包和模块时还偶有迷惑的同学。&lt;/p&gt;&lt;h2 id=&quot;一什么是包模块&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;text-align: center;font-size: 1.75rem;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;一、什么是包、模块&lt;/h2&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go 语言官方文档&amp;nbsp;&lt;a href=&quot;https://tip.golang.org/doc/code&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;How to Write Go Code&lt;/a&gt;&amp;nbsp;对&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;包&lt;/strong&gt;&amp;nbsp;和&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块&lt;/strong&gt;&amp;nbsp;有比较清晰的介绍。&lt;/p&gt;&lt;blockquote style=&quot;box-sizing: inherit;margin: 1em 0px;padding: 0px 2em;border-left: 3px solid transparent;font-family: &amp;#39;Helvetica Neue&amp;#39;, Helvetica, sans-serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;A package is a collection of source files in the same directory that are compiled together.&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;A module is a collection of related Go packages that are released together.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;当然，远不止这两句话。我们已经熟悉一些点，我这里先列举一下：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;一个文件夹对应着一个包，包名是文件夹的路径名，而非声明的&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;package xxxx&lt;/code&gt;，包名&lt;em style=&quot;box-sizing: inherit&quot;&gt;通常&lt;/em&gt;与目录名一致&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;同一个包中所有 .go 文件，声明的&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;package xxx&lt;/code&gt;不能冲突，都可以相互访问变量、函数、结构等&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;import 导入的是包名&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;一个包中可以有多个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;init()&lt;/code&gt;，会在被导入的时候执行。同一个文件中的多个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;init()&lt;/code&gt;按顺序执行，不同文件中的多个不保证执行顺序。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr style=&quot;box-sizing: inherit;height: 1px;border-right: 0px;border-bottom: 0px;border-left: 0px;border-top-color: initial;border-image: initial;border-top-style: solid;margin: 50px auto;padding: 0px;max-width: 300px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;/&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;模块也是文件夹，有个 go.mod 文件，包含一个或多个包&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;模块有模块路径 (module path)，通常是个仓库地址&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;em style=&quot;box-sizing: inherit&quot;&gt;一个简单的、典型的 Go 项目的目录结构和文件可能像下边这样&lt;/em&gt;：&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102059177492365999943.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;接下来，将详细地说明：&lt;strong style=&quot;box-sizing: inherit&quot;&gt;在Go语言中，包（Package）是代码组织和重用的基本单位，而模块是控制版本和管理依赖的单元&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;还包括一些可能大家不太清楚的问题解释，比如：子模块、版本编号规则与发布、go.sum的作用、indirect 依赖模块、包的循环引入、模块的版本冲突、仓库地址和模块路径不一致等问题。&lt;/p&gt;&lt;h2 id=&quot;二包---组织代码和复用的单元&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;text-align: center;font-size: 1.75rem;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;二、包 - 组织代码和复用的单元&lt;/h2&gt;&lt;blockquote style=&quot;box-sizing: inherit;margin: 1em 0px;padding: 0px 2em;border-left: 3px solid transparent;font-family: &amp;#39;Helvetica Neue&amp;#39;, Helvetica, sans-serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;A package is a source code organization unit: it defines a context for identifier names, determining the visibility of an identifier within the package. Every package is associated with a directory of the same name. All the files in a package’s directory must declare the same package name. – Go doc&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;包是源代码的组织单位：它为标识符名称定义了一个上下文，决定了一个标识符在包内的可见性。每个包都与一个同名的目录关联。包目录中的所有文件必须声明相同的包名。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这是一种组织和封装代码的方式。这种方式使得代码结构清晰，易于理解和维护。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;更直白的翻译一下：&lt;strong style=&quot;box-sizing: inherit&quot;&gt;Go 程序组织代码的基本单位是包（package）&lt;/strong&gt;，就像说生物体的基本组成单位是细胞一样。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;包为什么是代码组织的基本单位&lt;/strong&gt;？接下来从命名空间、封装以及代码复用等方面聊聊。&lt;/p&gt;&lt;h3 id=&quot;21-命名空间&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;2.1 命名空间&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;命名空间(namespace)&lt;/strong&gt;&amp;nbsp;是一个用于管理变量名的区域范围，要保证同一个命名空间内的变量名（更确切的应该是标识符名称）是唯一的。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go语言中，每个包都会提供一个独立的命名空间。这意味着&lt;strong style=&quot;box-sizing: inherit&quot;&gt;在不同的包中，你可以使用相同的标识符名称&lt;/strong&gt;，而不会产生冲突。而在同一个包内，不同文件之间中定义的变量、方法，都可以直接进行访问。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;避免命名冲突&lt;/strong&gt;极大地提高了代码的可维护性。特别是在大型程序中，不同模块或库很可能会使用相同的变量名、函数名。&lt;/p&gt;&lt;h3 id=&quot;22-封装&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;2.2 封装&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;封装&lt;/strong&gt;是&lt;strong style=&quot;box-sizing: inherit&quot;&gt;将数据和操作这些数据的方法组合&lt;/strong&gt;在一起的机制，其主要目标是&lt;strong style=&quot;box-sizing: inherit&quot;&gt;隐藏对象的内部状态和实现细节，只暴露必要的接口给外部使用者&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;封装通常用于面向对象编程（OOP）中，可以通过类和对象来实现。而 Go 语言并不是传统意义上的面向对象编程语言，但其&lt;strong style=&quot;box-sizing: inherit&quot;&gt;通过使用包也实现了良好的封装&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;在一个包内部，类型、变量、常量和函数分为耳熟能详的两类：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;可导出（Exported）&lt;/strong&gt;：大写字母开头，可以被包外的代码访问&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;非可导出（Unexported）&lt;/strong&gt;：以小写字母开头，只能在包内访问&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这种方式提供了良好的封装性，可以隐藏实现细节，只暴露必要的接口给其他包。而通过大小写字母来开头的方式来实现，比一些复杂的类的&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;public&lt;/code&gt;，&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;extern&lt;/code&gt;&amp;nbsp;之类的方式，更简洁明了。&lt;/p&gt;&lt;h3 id=&quot;23-代码复用&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;2.3 代码复用&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;代码复用是软件开发中的一个关键实践，通过代码复用，可以提高开发效率、减少错误、提高代码质量和维护性。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go语言的包也是代码重用的基本单位。通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;import&lt;/code&gt;&amp;nbsp;语句可以引入其他包。&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;标准库&lt;/strong&gt;：Go语言提供了丰富的标准库，这些标准库以包的形式组织，涵盖了常见的功能模块，如I/O操作、字符串处理、网络编程等。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;自定义包&lt;/strong&gt;：开发者可以创建自定义包，在一个仓库/模块中，创建多个包，包之间可以引入&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;第三方包&lt;/strong&gt;：Go语言生态系统中有大量第三方包，通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get&lt;/code&gt;&amp;nbsp;命令可以轻松获取和使用这些包。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get -u&lt;/code&gt;&amp;nbsp;命令+包的路径，可以从指定的远程仓库中获取包，并将其安装到本地的Go环境中。比如：&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap;text-align: center&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102100177492366064594.png&quot;&gt;&lt;/p&gt;&lt;h3 id=&quot;24-其他语言类似的概念&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;2.4 其他语言类似的概念&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go语言中的包概念在其他语言中也有类似的概念，主要用于组织和管理代码，但是不完全相同。接下来，以我用过的几类语言来比较一下。&lt;/p&gt;&lt;h4 id=&quot;python&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Python&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;在Python中，有&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块(module)&lt;/strong&gt;&amp;nbsp;和&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;包(package)&lt;/strong&gt;&amp;nbsp;的概念。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块&lt;/strong&gt;是一个包含Python定义和语句的文件，一个文件有独立的命名空间。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;包&lt;/strong&gt;是一个包含多个模块的目录，其中有个&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;__init__.py&lt;/code&gt;&amp;nbsp;文件，正是这个文件，使得包在导入时，也被视为一个特殊的模块。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Python的包可以用来组织模块，类似于Go的包。&lt;/p&gt;&lt;h4 id=&quot;c&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;C++&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;C++好像没有直接对应Go的包的概念，但是C++有显式的 namespace 支持。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;命名空间非常灵活，可以跨越不同的目录和文件，还支持嵌套命名空间来进一步组织代码。换句话说，开发者需要自己来组织命名空间。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;此外，C++的头文件和源文件的组织方式也可以看作是一种代码管理的方式，虽然它不像Go的包那样强大。&lt;/p&gt;&lt;h4 id=&quot;java&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Java&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;因为之前开发实时计算任务，也有用到 Java 和 Scala。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Java的代码组织单元是类（Class）。每个 Java 源文件通常只包含一个公共类，该文件名与公共类名相同，并以&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;.java&lt;/code&gt;&amp;nbsp;结尾。这种文件级别的组织方式使得Java程序易于管理和维护。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Java中，包（Package）用于组织类、接口以及其他子包，提供了命名空间的管理机制，可以避免命名冲突。包名使用点分隔符来分级，例如&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;java.util&lt;/code&gt;，其中&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;java&lt;/code&gt;&amp;nbsp;是顶级包，&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;util&lt;/code&gt;&amp;nbsp;是它的子包。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;看上去跟 Go 的导入是不是还有点像？&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;import&amp;nbsp;com.google.gson.Gson;&lt;/pre&gt;&lt;h2 id=&quot;三模块---依赖管理和版本控制的单元&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;text-align: center;font-size: 1.75rem;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;三、模块 - 依赖管理和版本控制的单元&lt;/h2&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;相对于包是组织代码的基本单元，&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块则是管理依赖和版本控制的基本单元&lt;/strong&gt;，两者的目标是不同的。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;关于模块的使用，&lt;a href=&quot;https://go.dev/doc/modules/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;Go 官方一系列文档&lt;/a&gt;提供了详细的介绍，包括版本号如何定义、如何发布、如何维护依赖等等。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;em style=&quot;box-sizing: inherit&quot;&gt;既然有了包这个概念，为什么还需要模块？&lt;/em&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;之所以会&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块通常包含了多个包&lt;/strong&gt;，最主要可能是实践中，&lt;strong style=&quot;box-sizing: inherit&quot;&gt;复用代码的粒度会比较细&lt;/strong&gt;，而&lt;strong style=&quot;box-sizing: inherit&quot;&gt;版本管理的没有那么必要那么细&lt;/strong&gt;。另外，模块通常要实现一系列的功能，很少有一个项目会只有一个包就可以完成的（虽然有些包和模块确实在一个文件夹中，也有的模块确实只有根目录一个包）。&lt;/p&gt;&lt;h3 id=&quot;31-版本管理功能&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;3.1 版本管理功能&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go&amp;nbsp;&lt;a href=&quot;https://go.dev/doc/modules/version-numbers&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;版本号&lt;/a&gt;&amp;nbsp;和&amp;nbsp;&lt;a href=&quot;https://go.dev/doc/modules/publishing&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;发布模块&lt;/a&gt;&amp;nbsp;两个文档简明地介绍如何发布模块版本。&lt;/p&gt;&lt;h4 id=&quot;语义化版本&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;语义化版本&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;文档里我们会看到&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;semantic version&lt;/strong&gt;，这个我们之前有提到过&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;&lt;a href=&quot;https://semver.org/lang/zh-CN/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;语义化版本&lt;/a&gt;&lt;/strong&gt;，版本号包括：不兼容的 API 修改的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;主版本号&lt;/strong&gt;、新增向下兼容特性的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;次版本号&lt;/strong&gt;、新增向下兼容的补丁的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;修订版本号&lt;/strong&gt;。最后还&lt;em style=&quot;box-sizing: inherit&quot;&gt;可以有&lt;/em&gt;个&lt;strong style=&quot;box-sizing: inherit&quot;&gt;预发布版本号&lt;/strong&gt;，通过横线连接一个字符串，意思是还没有到达前边的标准版本。&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102100177492366076348.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;语义化版本的好处，是能让我们一眼就能看出哪些版本更新，哪些版本之间是兼容的。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;比如以下版本之间，越往右版本越高（越新）。&lt;/p&gt;&lt;blockquote style=&quot;box-sizing: inherit;margin: 1em 0px;padding: 0px 2em;border-left: 3px solid transparent;font-family: &amp;#39;Helvetica Neue&amp;#39;, Helvetica, sans-serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;1.0.0-alpha &amp;lt; 1.0.0 &amp;lt; 2.0.0 &amp;lt; 2.1.0 &amp;lt; 2.1.1&lt;/p&gt;&lt;/blockquote&gt;&lt;h4 id=&quot;通过-git-tag-标记版本&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;通过 git tag 标记版本&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go 的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块版本&lt;/strong&gt;，依赖于版本控制仓库，可以使用 Git，也支持 Subversion, Mercurial, Bazaar, Fossil 等其他版本控制的形式。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;因为我们主要使用 Git，接下来主要介绍基于 Git 的版本发布。Go 模块路径，也就是我们在调用&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go mod init&lt;/code&gt;&amp;nbsp;的时候后边加的路径，通常是一个仓库名。这样做有两个功能：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;可以唯一标识一个模块&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;可以指示下载地址&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这里跳过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;git init/add&lt;/code&gt;&amp;nbsp;等前序操作，到&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;git commit&lt;/code&gt;&amp;nbsp;之后使用&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;git tag&lt;/code&gt;，比如我们要发布第一个版本&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;v0.1.0&lt;/code&gt;：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;&amp;quot;Init:&amp;nbsp;v0.1.0&amp;quot;&amp;nbsp;git&amp;nbsp;tag&amp;nbsp;v0.1.0&amp;nbsp;git&amp;nbsp;push&amp;nbsp;origin&amp;nbsp;v0.1.0&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;推送到远端仓库之后，我们可以通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go list&lt;/code&gt;&amp;nbsp;指令查看模块的可用版本：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;font-variant-ligatures: common-ligatures&quot;&gt;✗&amp;nbsp;go&amp;nbsp;list&amp;nbsp;-m&amp;nbsp;git.woa.com/jasonzxpan/m1&amp;nbsp;git.woa.com/jasonzxpan/m1&amp;nbsp;v0.1.0&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这里再提一下前面提到的&amp;nbsp;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;预发布版本号&lt;/strong&gt;：如果我们提供的包/模块，不是稳定的版本，但同时也需要打 tag 的话，就可以使用像&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;v0.1.0-beta.1&lt;/code&gt;&amp;nbsp;这样的预发布版本号。这种版本不必保证版本的稳定性。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;如果我们做了变动需要发布，可以再根据前面的【语义化版本】的规则，打上新的 tag，比如&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;v0.1.1&lt;/code&gt;&amp;nbsp;并推送到仓库。&lt;/p&gt;&lt;h3 id=&quot;32-使用第三方包和模块&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;3.2 使用第三方包和模块&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go 语言的标准库是随着 Go 版本发布的，因此在编写Go代码时，引入标准库的包（例如&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;import &amp;quot;fmt&amp;quot;&lt;/code&gt;）不需要指定具体的版本号。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;你可以通过 IDE 点到源代码查看中，在Mac上，默认安装的 Go 语言通常位于&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;/usr/local/opt/go/libexec&lt;/code&gt;&amp;nbsp;目录下。这里边有 VERSION 文件，标识当前安装的 Go 语言版本及其标准库的版本信息。&lt;/p&gt;&lt;h4 id=&quot;指定版本的依赖&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;指定版本的依赖&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;本节中，第三方包和模块是指除了&lt;strong style=&quot;box-sizing: inherit&quot;&gt;模块自身中的包&lt;/strong&gt;与&lt;strong style=&quot;box-sizing: inherit&quot;&gt;标准库&lt;/strong&gt;之外的包和模块。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;我们上边创建的模块&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;git.woa.com/jasonzxpan/m1&lt;/code&gt;，假设其中有一个包&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;p1&lt;/code&gt;，其中有个导出函数&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;M1P1F1()&lt;/code&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;我们再创建一个模块&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go mod init git.woa.com/jasonzxpan/m2&lt;/code&gt;，要使用这个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;m1/p1&lt;/code&gt;&amp;nbsp;的包，可以直接在文件中引入。&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;package&amp;nbsp;main&amp;nbsp;import&amp;nbsp;(&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m1p1&amp;nbsp;&amp;quot;git.woa.com/jasonzxpan/m1/p1&amp;quot;&amp;nbsp;)&amp;nbsp;func&amp;nbsp;main()&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m1p1.M1P1F1()&amp;nbsp;}&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这时候可以直接通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go mod tidy&lt;/code&gt;&amp;nbsp;让其自己分析依赖，并且获得&lt;strong style=&quot;box-sizing: inherit&quot;&gt;最新版本&lt;/strong&gt;的包。&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;font-variant-ligatures: common-ligatures&quot;&gt;➜&amp;nbsp;&amp;nbsp;m2&amp;nbsp;git:(master)&amp;nbsp;✗&amp;nbsp;go&amp;nbsp;mod&amp;nbsp;tidy&amp;nbsp;go:&amp;nbsp;finding&amp;nbsp;module&amp;nbsp;for&amp;nbsp;package&amp;nbsp;git.woa.com/jasonzxpan/m1/p1&amp;nbsp;go:&amp;nbsp;downloading&amp;nbsp;git.woa.com/jasonzxpan/m1&amp;nbsp;v0.1.1&amp;nbsp;go:&amp;nbsp;found&amp;nbsp;git.woa.com/jasonzxpan/m1/p1&amp;nbsp;in&amp;nbsp;git.woa.com/jasonzxpan/m1&amp;nbsp;v0.1.1&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get&lt;/code&gt;&amp;nbsp;可以让我们获得指定版本的模块：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;go&amp;nbsp;get&amp;nbsp;git.woa.com/jasonzxpan/m1/p1@v0.1.0&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;如果要&lt;strong style=&quot;box-sizing: inherit&quot;&gt;更新某个模块&lt;/strong&gt;，也可以用&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get -u&lt;/code&gt;&amp;nbsp;来更新：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;默认拉取最新的&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get -u example.com/mypackage&lt;/code&gt;，但是要先删掉 go.mod 中对应的 require 之前指定的版本。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;也可以直接指定 latest 版本，&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get -u example.com/mypackage@latest&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4 id=&quot;替换模块依赖---repalce&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;替换模块依赖 -&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;repalce&lt;/code&gt;&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;有些场景，我们需要替换掉依赖远端的第三方库：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;依赖自己写的模块，没有稳定的版本，在开发过程中还需要不断调整&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;依赖别人写的模块，但是需要&lt;strong style=&quot;box-sizing: inherit&quot;&gt;调试或者增加一些特性&lt;/strong&gt;，可以从源仓库 fork，然后在本地开发，然后push到自己的仓库&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;无论是哪种场景，大概的操作流程都类似：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;将第三方模块，clone 到本地&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;通过 replace 的方式，修改 go.mod 中的依赖，替换成本地目录&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;开发过程、修改第三方模块；完成开发，推送第三方模块&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;去掉 replace 到本地的依赖：&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: square;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;依赖自己模块的，去掉replace，指向正式版本&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;依赖 fork 自别人仓库的，通过 replace 的方式，指向自己fork的版本&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;仍以上边 m2 依赖 m1 模块为例，我们可以直接通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;replace&lt;/code&gt;，在开发过程中使用本地的&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;m1&lt;/code&gt;：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;go&amp;nbsp;mod&amp;nbsp;edit&amp;nbsp;-replace=git.woa.com/jasonzxpan/m1@v0.1.1=../m1&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;类似地，可以替换成远端的仓库：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;go&amp;nbsp;mod&amp;nbsp;edit&amp;nbsp;-replace=git.code.oa.com/trpc-go/trpc-go=git.woa.com/trpc-go/trpc-go@v0.15.0&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;其实，还有另外一种常见场景，就是后边会提到的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;多个模块的，可能会有直接&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;replace xxx =&amp;gt; ../..&lt;/code&gt;&amp;nbsp;的操作&lt;/strong&gt;，比如，grpc-go 子模块 grpc-go/examples 中的 go.mod&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap;text-align: center&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102100177492366043324.png&quot;&gt;&lt;/p&gt;&lt;h4 id=&quot;为什么需要间接依赖&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;为什么需要间接依赖&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;如果我们项目复杂点，打开 go.mod 文件，会看到一些信息。 除了 module_path、Go 版本以及直接依赖的模块和版本信息之外，还有另外一个&lt;strong style=&quot;box-sizing: inherit&quot;&gt;间接依赖&lt;/strong&gt;。与直接依赖类似，也是模块路径和版本号，区别在于最后有个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;// indirect&lt;/code&gt;&amp;nbsp;的注释，其实上节图 grpc-go/examples 中就有。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;为了简明，我们再以被广泛使用的 uber 日志库 zap 的 go.mod 为例，可以看到有三个间接依赖的模块：&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102100177492366093472.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;我们可以理解间接依赖是指：如果我们直接使用&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;moduleA&lt;/code&gt;&amp;nbsp;中的包，而&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;moduleA&lt;/code&gt;&amp;nbsp;依赖&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;moduleB&lt;/code&gt;，那么&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;moduleB&lt;/code&gt;&amp;nbsp;就是我们模块的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;间接依赖&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;是不是 go.mod 会将所有间接依赖都列出来？答案是&lt;strong style=&quot;box-sizing: inherit&quot;&gt;否定的&lt;/strong&gt;。以上边的依赖关系来说，只有 moduleA 的 go.mod 文件中，没有指定 moduleB 的版本，才会在我们的自己的模块 go.mod 文件中指定间接依赖的版本。如果 moduleA 已经指定了 moduleB 的版本，就不需要指定了。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;运行&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go mod tidy&lt;/code&gt;&amp;nbsp;命令来更新你的&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go.mod&lt;/code&gt;文件，这个命令会添&lt;strong style=&quot;box-sizing: inherit&quot;&gt;加缺失的模块，删除无用的模块，以及更新间接依赖的版本&lt;/strong&gt;。&lt;/p&gt;&lt;hr style=&quot;box-sizing: inherit;height: 1px;border-right: 0px;border-bottom: 0px;border-left: 0px;border-top-color: initial;border-image: initial;border-top-style: solid;margin: 50px auto;padding: 0px;max-width: 300px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;/&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;那究竟为什么需要指定间接依赖的版本呢？&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;记录间接依赖的版本信息是为了确保项目的构建稳定性和可重现性&lt;/strong&gt;。因为间接依赖的版本可能会影响直接依赖模块的行为和版本兼容性。只有记录清楚所有依赖的版本，才能够重现完全相同的依赖版本树，从而避免由于间接依赖的不一致而导致的问题。&lt;/p&gt;&lt;h3 id=&quot;33-单仓库多模块&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;3.3 单仓库多模块&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go 的官方文档中，有子包 sub-package 的表述，但是没有 sub-module 的表述。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;但我们能看到部分项目中，可能存在多个 go.mod 的情况：模块中还有模块的，其实&lt;strong style=&quot;box-sizing: inherit&quot;&gt;外层目录是一个模块和子目录是另外一个模块，并非真正意义上的子模块&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;在&amp;nbsp;&lt;a href=&quot;https://tip.golang.org/doc/code&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;How to Write Go Code&lt;/a&gt;&amp;nbsp;的文档中，有这么一段话，也描述包、模块、仓库的关系：&lt;/p&gt;&lt;blockquote style=&quot;box-sizing: inherit;margin: 1em 0px;padding: 0px 2em;border-left: 3px solid transparent;font-family: &amp;#39;Helvetica Neue&amp;#39;, Helvetica, sans-serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;A Go repository typically contains only one module, located at the root of the repository. A file named&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go.mod&lt;/code&gt;&amp;nbsp;there declares the module path: the import path prefix for all packages within the module.&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;The module contains the packages in the directory containing its&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go.mod&lt;/code&gt;&amp;nbsp;file as well as subdirectories of that directory, up to the next subdirectory containing another&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go.mod&lt;/code&gt;&amp;nbsp;file (if any).&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;但是，上边提到了模块包含当前目录、以及所有子目录的中的包。但是如果一个子目录包含另外一个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go.mod&lt;/code&gt;&amp;nbsp;文件，则这个目录中及其子目录的包，不属于当前模块。&lt;/p&gt;&lt;h4 id=&quot;多模块的项目&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;多模块的项目&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;我们确实见到过类似的项目，比如 trpc-go和 grpc-go 的仓库中都有多个 go.mod 文件，这就意味着这些仓库中有多个模块。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这些&lt;em style=&quot;box-sizing: inherit&quot;&gt;子模块&lt;/em&gt;大多是依赖顶层模块，或者项目的一些工具。我们以 grpc-go 仓库为例：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;grpc-go 是 gRPC Go 项目的根模块，Go版本的gRPC 实现都在这模块中&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;grpc-go/cmd/protoc-gen-go-grpc 是使用 gRPC Go 时，要通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;protoc&lt;/code&gt;&amp;nbsp;将 .proto文件转换成Go语言库，其具体使用的工具就是这个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;protoc-gen-go-grpc&lt;/code&gt;。该模块本身只有根目录那一个包&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;grpc-go/examples 是 gRPC Go 的示例模块，其中有三个子包&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102101177492366175456.png&quot;&gt;&lt;/p&gt;&lt;h4 id=&quot;为什么要多模块&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;为什么要多模块&lt;/h4&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;多个模块有关联性，但是又不那么强烈的耦合&lt;/strong&gt;的场景，就适合拆分成多个模块。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;比如 grpc-go/examples 模块，只是 grpc-go 的示例，单独放个仓库过于简单，没有必要。而如果直接放在 grpc-go 模块中作为一个包，不加 go.mod 单独一个模块，又会对 grpc-go 包的纯洁性有影响——用户不会依赖 examples 包。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;另外，这样划分，客观上还带来了一些好处：&lt;/p&gt;&lt;ul style=&quot;box-sizing: inherit;padding: 0px 0px 0px 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;依赖管理是独立的&lt;/strong&gt;：这里的 examples 依赖等不会影响到外层 grpc-go 模块的依赖；而examples 中的依赖，也可以依赖 grpc-go 中没有的或者版本不一样的模块&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;版本管理是独立的&lt;/strong&gt;：这里examples直接没有打版本的需要，我们看另外一个 protoc-gen-go-grpc 的版本情况。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;我们可以通过&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go list -m -versions&lt;/code&gt;&amp;nbsp;来看两个模块的版本信息，可以看到这个工具只有到6个版本，而根模块有到 v1.66.0-dev 等几十个版本：&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap;text-align: center&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102101177492366130904.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;如何对不同的模块不同的版本？在官方文档&amp;nbsp;&lt;a href=&quot;https://go.dev/doc/modules/managing-source&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;Managing module source&lt;/a&gt;&amp;nbsp;中有介绍。根目录直接打 v1.2.1，子目录打标签时候带上目录即可。比如我们看到 protoc-gen-go-grpc 对应的版本在仓库中有打对应的 tag 如&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;cmd/protoc-gen-go-grpc/v1.1.0&lt;/code&gt;：&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102101177492366162201.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;可以上下层次，也可以两个目录并行，比如官方介绍的：&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102101177492366154022.png&quot;&gt;&lt;/p&gt;&lt;h2 id=&quot;四其他疑惑&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;text-align: center;font-size: 1.75rem;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;四、其他疑惑&lt;/h2&gt;&lt;h3 id=&quot;41-gosum-里边有什么&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;4.1 go.sum 里边有什么&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;在官方文档&amp;nbsp;&lt;a href=&quot;https://go.dev/doc/modules/managing-dependencies#adding_dependency&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;管理依赖&lt;/a&gt;&amp;nbsp;一文中，有这样一段描述：&lt;/p&gt;&lt;blockquote style=&quot;box-sizing: inherit;margin: 1em 0px;padding: 0px 2em;border-left: 3px solid transparent;font-family: &amp;#39;Helvetica Neue&amp;#39;, Helvetica, sans-serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;When you add dependencies, Go tools also create a go.sum file that contains checksums of modules you depend on. Go uses this to verify the integrity of downloaded module files, especially for other developers working on your project.&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;Include the go.mod and go.sum files in your repository with your code.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;当添加依赖（创建 go.mod）的同时，也会创建 go.sum 文件。go.sum 记录了项目中使用的每个依赖模块的模块路径（module path）以及对应的校验和，用于验证依赖模块在下载时的完整性。&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get&lt;/code&gt;&amp;nbsp;和&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go mod tidy&lt;/code&gt;&amp;nbsp;的时候，在更新 go.mod 的同时，也会更新 go.sum。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;go.mod 文件定义了项目的模块依赖关系和版本约束，而 go.sum 文件则提供了依赖模块的安全性保证，确保每次构建时都能使用正确的依赖版本，可以防止恶意或不良网络条件下的&lt;strong style=&quot;box-sizing: inherit&quot;&gt;中间人攻击&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;strong style=&quot;box-sizing: inherit&quot;&gt;go.sum 和 go.mod 一样，都要加入到版本控制中。&lt;/strong&gt;&lt;/p&gt;&lt;h3 id=&quot;42-依赖下载到本地存放在哪里&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;4.2 依赖下载到本地，存放在哪里&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;Go Modules 会将依赖下载到本地的模块缓存目录，默认情况下，这个目录是&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;$GOPATH/pkg/mod&lt;/code&gt;。如果没有设置&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;GOPATH&lt;/code&gt;&amp;nbsp;环境变量，默认的&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;GOPATH&lt;/code&gt;&amp;nbsp;是用户主目录下的&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go&lt;/code&gt;&amp;nbsp;目录：&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102102177492366298083.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;如果缓存的模块太多导致磁盘占用太大，或者缓存的模块出现问题导致构建失败，这些情形下，我们可以调用&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go clean -modcache&lt;/code&gt;&amp;nbsp;来&lt;strong style=&quot;box-sizing: inherit&quot;&gt;清理模块缓存&lt;/strong&gt;，这会删除&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;$GOPATH/pkg/mod&lt;/code&gt;&amp;nbsp;目录中的所有内容。&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102102177492366262832.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;对比之下还有&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go clean&lt;/code&gt;&amp;nbsp;指令，他只是用来清理项目自身构建的二进制文件、测试缓存文件、临时文件等。&lt;/p&gt;&lt;h3 id=&quot;43-如果仓库地址和模块路径不一样怎么办&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;4.3 如果仓库地址和模块路径不一样怎么办？&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;虽然仓库地址是 github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc，但是他模块路径自己写的是 google.golang.org/grpc/cmd/protoc-gen-go-grpc，这两者是不一致的，到时候会报错：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;font-variant-ligatures: common-ligatures&quot;&gt;✗&amp;nbsp;go&amp;nbsp;get&amp;nbsp;github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc&amp;nbsp;go:&amp;nbsp;downloading&amp;nbsp;github.com/grpc/grpc-go&amp;nbsp;v1.65.0&amp;nbsp;go:&amp;nbsp;downloading&amp;nbsp;github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc&amp;nbsp;v1.4.0&amp;nbsp;go:&amp;nbsp;github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc@upgrade&amp;nbsp;(v1.4.0)&amp;nbsp;requires&amp;nbsp;github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc@v1.4.0:&amp;nbsp;parsing&amp;nbsp;go.mod:&amp;nbsp;module&amp;nbsp;declares&amp;nbsp;its&amp;nbsp;path&amp;nbsp;as:&amp;nbsp;google.golang.org/grpc/cmd/protoc-gen-go-grpc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;but&amp;nbsp;was&amp;nbsp;required&amp;nbsp;as:&amp;nbsp;github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;你需要在你的&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go.mod&lt;/code&gt;文件中添加一个&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;replace&lt;/code&gt;&amp;nbsp;指令，将&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;github.com&lt;/code&gt;&amp;nbsp;模块名替换为&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;google.golang.org&lt;/code&gt;&amp;nbsp;开头的模块名。例如：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;font-variant-ligatures: common-ligatures&quot;&gt;replace&amp;nbsp;github.com/grpc/grpc-go/cmd/protoc-gen-go-grpc&amp;nbsp;=&amp;gt;&amp;nbsp;google.golang.org/grpc/cmd/protoc-gen-go-grpc&amp;nbsp;v1.4.0&lt;/pre&gt;&lt;hr style=&quot;box-sizing: inherit;height: 1px;border-right: 0px;border-bottom: 0px;border-left: 0px;border-top-color: initial;border-image: initial;border-top-style: solid;margin: 50px auto;padding: 0px;max-width: 300px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;/&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;比如我们之前的仓库地址是 git.code.oa.com, 之后迁移到了 git.woa.com，那很多之前很多代码仓库的 module path 都是以 git.code.oa.com 开头的。这时候如果直接 go get git.woa.com/trpc/trpc-go，可能会遇到跟上边一样的错误：&lt;/p&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;box-sizing: inherit;font-size: 0.95em;color: rgb(248, 248, 242);background-color: rgb(39, 40, 34)&quot;&gt;✗&amp;nbsp;go&amp;nbsp;get&amp;nbsp;git.woa.com/trpc-go/trpc-go&amp;nbsp;go:&amp;nbsp;git.woa.com/trpc-go/trpc-go@upgrade&amp;nbsp;(v0.18.1)&amp;nbsp;requires&amp;nbsp;git.woa.com/trpc-go/trpc-go@v0.18.1:&amp;nbsp;parsing&amp;nbsp;go.mod:&amp;nbsp;module&amp;nbsp;declares&amp;nbsp;its&amp;nbsp;path&amp;nbsp;as:&amp;nbsp;git.code.oa.com/trpc-go/trpc-go&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;but&amp;nbsp;was&amp;nbsp;required&amp;nbsp;as:&amp;nbsp;git.woa.com/trpc-go/trpc-go&lt;/pre&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;而如果直接使用老仓库地址，&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;go get git.code.oa.com/trpc-go/trpc-go&lt;/code&gt;&amp;nbsp;可能老的服务已经停止了，无法获得对应的包。除了使用上边replace 之外，还可以使用公司内提供的 GOPROXY：&lt;/p&gt;&lt;blockquote style=&quot;box-sizing: inherit;margin: 1em 0px;padding: 0px 2em;border-left: 3px solid transparent;font-family: &amp;#39;Helvetica Neue&amp;#39;, Helvetica, sans-serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;问：为什么&amp;nbsp;&lt;a href=&quot;https://goproxy.woa.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;goproxy.woa.com&lt;/a&gt;&amp;nbsp;能去 git 下载到 import path 为 git.code.oa.com 的库？&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit&quot;&gt;答：是因为&amp;nbsp;&lt;a href=&quot;https://goproxy.woa.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; style=&quot;box-sizing: inherit;color: black;padding-bottom: 2px;border-bottom: 1px solid&quot;&gt;goproxy.woa.com&lt;/a&gt;&amp;nbsp;服务 git clone 时会自动将&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;git.code.oa.com&lt;/code&gt;&amp;nbsp;替换为&amp;nbsp;&lt;code style=&quot;box-sizing: inherit;font-size: 0.95em;background: rgb(249, 249, 249);font-family: Consolas, Courier, &amp;#39;Courier New&amp;#39;, STKaiti, KaiTi, SimKai, monospace;hyphens: none&quot;&gt;git.woa.com&lt;/code&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3 id=&quot;44-导入的多个包依赖同一模块其版本冲突如何处理&quot; style=&quot;box-sizing: inherit;padding: 0px;margin: 60px 0px 30px;line-height: 1.25;font-size: 24px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;4.4 导入的多个包依赖同一模块，其版本冲突如何处理&lt;/h3&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;对于版本冲突，Go Modules 使用了一种称为“最小版本选择”（Minimal Version Selection, MVS）的机制。MVS 机制确保在构建过程中使用的每个模块的版本是&lt;strong style=&quot;box-sizing: inherit&quot;&gt;所有依赖项中要求的最低版本&lt;/strong&gt;。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;考虑下图中的示例。主模块需要版本 1.2 或更高版本的模块 A，以及版本 1.2 或更高版本的模块 B。A 1.2 和 B 1.2 分别需要 C 1.3 和 C 1.4。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;C 1.3 和 C 1.4 都需要 D 1.2。所以根据 MVS 的机制，加粗黑框中的模块将会被选中。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap;text-align: center&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102102177492366246519.svg&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;这里你可能有疑问，C 的两个冲突版本 1.3 和 1.4 中最小的不是1.3吗？为什么选择1.4。MVS 不是要找依赖的最低版本，而是找&lt;strong style=&quot;box-sizing: inherit&quot;&gt;满足所有模块依赖的最低版本&lt;/strong&gt;，比如 B 1.2 如果使用到了 C 1.4 中的新增接口，那么 C 1.3 是不能满足 B 1.2 的需求的。所以，所有依赖项对 C 模块依赖的最低版本是 1.4。&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;B 和 D 的更高版本可用，但 MVS 不会选择它们，因为没有任何内容需要它们&lt;/p&gt;&lt;hr style=&quot;box-sizing: inherit;height: 1px;border-right: 0px;border-bottom: 0px;border-left: 0px;border-top-color: initial;border-image: initial;border-top-style: solid;margin: 50px auto;padding: 0px;max-width: 300px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;/&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;如果发生依赖的冲突无法解决，可能会涉及到&lt;strong style=&quot;box-sizing: inherit&quot;&gt;升级依赖、降级依赖、替代、排除&lt;/strong&gt;等方法来解决&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102102177492366237245.svg&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102102177492366280905.svg&quot;&gt;&lt;/p&gt;&lt;p style=&quot;box-sizing: inherit;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &amp;#39;PingFang SC&amp;#39;, Cambria, Cochin, Georgia, Times, &amp;#39;Times New Roman&amp;#39;, serif;font-size: 17.6px;font-variant-ligatures: common-ligatures;text-wrap-mode: wrap&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102103177492366377020.svg&quot;&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331102103177492366314393.svg&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 31 Mar 2026 10:19:58 +0800</pubDate></item><item><title>名言一则</title><link>https://2799.top/2026/03/6.html</link><description>&lt;p&gt;伟大的人不是生下来就伟大的，而是在成长过程中显示其伟大的&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331101129177492308969332.jpeg&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Sat, 14 Mar 2026 09:18:14 +0800</pubDate></item><item><title>实质的大道理往往很简洁</title><link>https://2799.top/2026/02/5.html</link><description>&lt;p&gt;实质的大道理都是很简单，如果如果讲的一大堆不知道说啥，那么这个作者肯定是自己不清楚，要不是为了凑字数要不是为了赚稿费。&lt;/p&gt;&lt;p&gt;原理到要一针见血地说出来那样才是一个技术人员或者一个管理者应该做到的事情&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://2799.top/zb_users/upload/2026/03/20260331101129177492308969332.jpeg&quot;&gt;&lt;/p&gt;</description><pubDate>Fri, 13 Feb 2026 20:00:15 +0800</pubDate></item><item><title>npm install卡住出现npm WARN old lockfile解决办法</title><link>https://2799.top/2025/10/4.html</link><description>&lt;h2 data-line=&quot;0&quot; id=&quot;问题描述：&quot; style=&quot;text-wrap-mode: wrap; margin: 1.4em 0px 0.8em; position: relative; word-break: break-all; border-bottom: 0px none rgb(63, 74, 84); color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; background-color: rgb(255, 255, 255);&quot;&gt;问题描述：&lt;/h2&gt;&lt;blockquote data-line=&quot;2&quot; style=&quot;text-wrap-mode: wrap; background-color: rgb(236, 236, 236); border-left: 4.8px solid rgb(53, 179, 120); color: rgb(63, 74, 84); padding: 0px 1.2em; line-height: 2em; margin: 20px 0px; overflow: auto; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px;&quot;&gt;&lt;p data-line=&quot;2&quot; style=&quot;line-height: 1.6; margin-top: 0.5rem; margin-bottom: 0.5rem;&quot;&gt;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;npm&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(0, 188, 212) !important; color: rgb(255, 255, 255) !important;&quot;&gt;npm&lt;/mark&gt;报错：&lt;mark class=&quot;searchJumper&quot; data-content=&quot;npm&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(0, 188, 212) !important; color: rgb(255, 255, 255) !important;&quot;&gt;npm&lt;/mark&gt;&amp;nbsp;install 出现&amp;quot;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;npm&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(0, 188, 212) !important; color: rgb(255, 255, 255) !important;&quot;&gt;npm&lt;/mark&gt;&amp;nbsp;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;warn&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(233, 30, 99) !important; color: rgb(255, 255, 255) !important;&quot;&gt;WARN&lt;/mark&gt;&amp;nbsp;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;old&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(0, 128, 0) !important; color: rgb(255, 255, 255) !important;&quot;&gt;old&lt;/mark&gt;&amp;nbsp;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;lockfile&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(255, 255, 0) !important; color: black !important;&quot;&gt;lockfile&lt;/mark&gt;&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;figure data-line=&quot;4&quot; style=&quot;text-wrap-mode: wrap; display: inline-flex; flex-direction: column; margin: 0px 0px 1em; text-align: center; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;img data-width=&quot;1975&quot; data-height=&quot;628&quot; src=&quot;https://2799.top/zb_users/upload/2025/10/20251020112851176093093116886.png&quot;&gt;&lt;/figure&gt;&lt;span style=&quot;text-wrap-mode: wrap; color: #3F4A54; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: #FFFFFF;&quot;&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 data-line=&quot;6&quot; id=&quot;解决办法：&quot; style=&quot;text-wrap-mode: wrap; margin: 1.4em 0px 0.8em; position: relative; word-break: break-all; border-bottom: 0px none rgb(63, 74, 84); color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; background-color: rgb(255, 255, 255);&quot;&gt;解决办法：&lt;/h2&gt;&lt;p data-line=&quot;8&quot; style=&quot;text-wrap-mode: wrap; line-height: 1.6; margin-top: 0.5rem; margin-bottom: 0.5rem; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;strong&gt;第一步：手动删掉 node_modules、package-lock.json 文件&lt;/strong&gt;&lt;/p&gt;&lt;p data-line=&quot;10&quot; style=&quot;text-wrap-mode: wrap; line-height: 1.6; margin-top: 0.5rem; margin-bottom: 0.5rem; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;strong&gt;第二步：更换&amp;nbsp;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;npm&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(0, 188, 212) !important; color: rgb(255, 255, 255) !important;&quot;&gt;npm&lt;/mark&gt;&amp;nbsp;源&lt;/strong&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;npmconfig&amp;nbsp;set&amp;nbsp;registry=https://registry.npmmirror.com&lt;/pre&gt;&lt;p data-line=&quot;10&quot; style=&quot;text-wrap-mode: wrap; line-height: 1.6; margin-top: 0.5rem; margin-bottom: 0.5rem; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;strong&gt;第三步：输入&lt;mark class=&quot;searchJumper&quot; data-content=&quot;npm&quot; style=&quot;visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; padding: 1px 0px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; margin: initial; background: rgb(0, 188, 212) !important; color: rgb(255, 255, 255) !important;&quot;&gt;npm&lt;/mark&gt;&amp;nbsp;install即可（那两个文件会被重新下载）&lt;/strong&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;npm&amp;nbsp;install&lt;/pre&gt;&lt;p data-line=&quot;10&quot; style=&quot;text-wrap-mode: wrap; line-height: 1.6; margin-top: 0.5rem; margin-bottom: 0.5rem; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure data-line=&quot;18&quot; style=&quot;text-wrap-mode: wrap; display: inline-flex; flex-direction: column; margin: 0px 0px 1em; text-align: center; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;&lt;img data-width=&quot;1737&quot; data-height=&quot;461&quot; src=&quot;https://2799.top/zb_users/upload/2025/10/20251020112851176093093189795.png&quot;&gt;&lt;/figure&gt;&lt;span style=&quot;text-wrap-mode: wrap; color: #3F4A54; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: #FFFFFF;&quot;&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-line=&quot;20&quot; style=&quot;text-wrap-mode: wrap; line-height: 1.6; margin-top: 0.5rem; margin-bottom: 0.5rem; color: rgb(63, 74, 84); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI Variable&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, ui-sans-serif, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 16px; background-color: rgb(255, 255, 255);&quot;&gt;就成功啦！&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 20 Oct 2025 11:23:34 +0800</pubDate></item><item><title>go get 拉取第三方包过慢、卡住解决方案</title><link>https://2799.top/2025/10/3.html</link><description>&lt;div class=&quot;newsview&quot; style=&quot;margin: 0px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); width: 714px; color: rgb(85, 85, 85); font-family: &amp;quot;Helvetica Neue&amp;quot;, Helvetica, &amp;quot;PingFang SC&amp;quot;, Tahoma, Arial, sans-serif; font-size: 15px; text-wrap-mode: wrap;&quot;&gt;&lt;div class=&quot;news_infos&quot; style=&quot;margin: 0px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); line-height: 24px; text-align: justify;&quot;&gt;&lt;h1 id=&quot;h1-u95EEu9898&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;问题&lt;/h1&gt;&lt;p style=&quot;margin-top: 15px; margin-bottom: 15px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;由于某种不可抗拒力量，go&quot; style=&quot;margin: initial; padding: 1px 0px; visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; background: rgb(255, 255, 0) !important; color: black !important;&quot;&gt;由于某种不可抗拒力量，go&lt;/mark&gt;&amp;nbsp;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;get&quot; style=&quot;margin: initial; padding: 1px 0px; visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; background: rgb(0, 188, 212) !important; color: rgb(255, 255, 255) !important;&quot;&gt;get&lt;/mark&gt;&amp;nbsp;&lt;mark class=&quot;searchJumper&quot; data-content=&quot;在国内下载特别慢&quot; style=&quot;margin: initial; padding: 1px 0px; visibility: inherit; font-style: inherit; box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 3px; border-radius: 3px; -webkit-text-fill-color: initial; text-shadow: initial; min-width: initial; display: inline; background: rgb(233, 30, 99) !important; color: rgb(255, 255, 255) !important;&quot;&gt;在国内下载特别慢&lt;/mark&gt;，&lt;/p&gt;&lt;h1 id=&quot;h1-u89E3u51B3u65B9u6848&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;解决方案&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;解决方案&lt;/h1&gt;&lt;h2 id=&quot;h2-u4EE3u7406u955Cu50CFu62C9u53D6&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;代理镜像拉取&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;代理镜像拉取&lt;/h2&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-wrap-mode: wrap; overflow-wrap: break-word; position: relative; display: inherit; font-size: 16px;&quot;&gt;go&amp;nbsp;env&amp;nbsp;-w&amp;nbsp;GO111MODULE=on
go&amp;nbsp;env&amp;nbsp;-w&amp;nbsp;GOPROXY=https://goproxy.io,direct#&amp;nbsp;设置不走&amp;nbsp;proxy&amp;nbsp;的私有仓库，多个用逗号相隔（可选）go&amp;nbsp;env&amp;nbsp;-w&amp;nbsp;GOPRIVATE=*.corp.example.com#&amp;nbsp;设置不走&amp;nbsp;proxy&amp;nbsp;的私有组织（可选）go&amp;nbsp;env&amp;nbsp;-w&amp;nbsp;GOPRIVATE=example.com/org_name&lt;/pre&gt;&lt;h2 id=&quot;h2-u56FDu5185u955Cu50CF&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;国内镜像&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;国内镜像&lt;/h2&gt;&lt;p style=&quot;margin-top: 15px; margin-bottom: 15px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;收集了几个代理地址：&lt;/p&gt;&lt;ul style=&quot;list-style-type: none;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://goproxy.cn,direct/&quot; style=&quot;margin: 0px; padding: 0px; text-decoration-line: none; color: rgb(51, 51, 51);&quot;&gt;https://goproxy.cn,direct&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://mirrors.aliyun.com/goproxy/&quot; style=&quot;margin: 0px; padding: 0px; text-decoration-line: none; color: rgb(51, 51, 51);&quot;&gt;https://mirrors.aliyun.com/goproxy/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://goproxy.io,direct/&quot; style=&quot;margin: 0px; padding: 0px; text-decoration-line: none; color: rgb(51, 51, 51);&quot;&gt;https://goproxy.io,direct&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4 id=&quot;h4-win-&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;win 下&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;win 下&lt;/h4&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-wrap-mode: wrap; overflow-wrap: break-word; position: relative; display: inherit; font-size: 16px;&quot;&gt;go&amp;nbsp;env&amp;nbsp;-w&amp;nbsp;GO111MODULE=on&lt;/pre&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-wrap-mode: wrap; overflow-wrap: break-word; position: relative; display: inherit; font-size: 16px;&quot;&gt;#&amp;nbsp;https://mirrors.aliyun.com/goproxy/&amp;nbsp;为例go&amp;nbsp;env&amp;nbsp;-w&amp;nbsp;GOPROXY=https://mirrors.aliyun.com/goproxy/&lt;/pre&gt;&lt;h4 id=&quot;h4-macos-linux&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;macOS 或 Linux&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;macOS 或 Linux&lt;/h4&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-wrap-mode: wrap; overflow-wrap: break-word; position: relative; display: inherit; font-size: 16px;&quot;&gt;export&amp;nbsp;GO111MODULE=on
export&amp;nbsp;GOPROXY=https://mirrors.aliyun.com/goproxy/&lt;/pre&gt;&lt;h2 id=&quot;h2--github-&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;通过 GitHub 镜像项目下载&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;通过 GitHub 镜像项目下载&lt;/h2&gt;&lt;p style=&quot;margin-top: 15px; margin-bottom: 15px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;golang在github上建立了一个镜像库，如&lt;a href=&quot;https://github.com/golang/net%E5%B0%B1%E5%AF%B9%E5%BA%94%E6%98%AF&quot; style=&quot;margin: 0px; padding: 0px; text-decoration-line: none; color: rgb(51, 51, 51);&quot;&gt;https://github.com/golang/net就对应是&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;https://golang.org/x/net%E7%9A%84%E9%95%9C%E5%83%8F%E5%BA%93%E3%80%82&quot; style=&quot;margin: 0px; padding: 0px; text-decoration-line: none; color: rgb(51, 51, 51);&quot;&gt;https://golang.org/x/net的镜像库。&lt;/a&gt;&amp;nbsp;要下载golang.org/x/net包，可以在本地创建包的目录后使用git clone来拉取相应包的源代码文件，具体操作如下：&lt;/p&gt;&lt;pre style=&quot;margin-top: 0px; margin-bottom: 0px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-wrap-mode: wrap; overflow-wrap: break-word; position: relative; display: inherit; font-size: 16px;&quot;&gt;mkdir&amp;nbsp;-p&amp;nbsp;$GOPATH/src/golang.org/x
cd&amp;nbsp;$GOPATH/src/golang.org/x
git&amp;nbsp;clone&amp;nbsp;https://github.com/golang/net.git&lt;/pre&gt;&lt;h1 id=&quot;h1-u6548u679C&quot; style=&quot;margin: 10px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;a name=&quot;效果&quot; class=&quot;reference-link&quot; style=&quot;margin: 0px; padding: 0px; color: rgb(51, 51, 51);&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot; style=&quot;margin: 0px; padding: 0px;&quot;&gt;&lt;/span&gt;效果&lt;/h1&gt;&lt;p style=&quot;margin-top: 15px; margin-bottom: 15px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;这里用的是阿里云镜像，没有修改镜像前，拉半天都没有反应，&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;img data-width=&quot;616&quot; data-height=&quot;58&quot; src=&quot;https://2799.top/zb_users/upload/2025/10/20251009161450175999769056544.png&quot;&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 15px; margin-bottom: 15px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;修改镜像后，&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;img data-width=&quot;587&quot; data-height=&quot;106&quot; src=&quot;https://2799.top/zb_users/upload/2025/10/20251009161450175999769042255.png&quot;&gt;&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;img data-width=&quot;586&quot; data-height=&quot;286&quot; src=&quot;https://2799.top/zb_users/upload/2025/10/20251009161450175999769025033.png&quot;&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;infos-aid&quot; style=&quot;margin: 0px auto; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); width: 714px; color: rgb(85, 85, 85); font-family: &amp;quot;Helvetica Neue&amp;quot;, Helvetica, &amp;quot;PingFang SC&amp;quot;, Tahoma, Arial, sans-serif; font-size: 15px; text-wrap-mode: wrap;&quot;&gt;&lt;div class=&quot;share&quot; style=&quot;margin: 0px; padding: 20px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);&quot;&gt;&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;/div&gt;</description><pubDate>Thu, 09 Oct 2025 15:50:25 +0800</pubDate></item></channel></rss>