第一章:Go 1.23模块自动启用机制终结与Goland项目启动危机概览
Go 1.23 正式移除了 GO111MODULE=auto 的隐式行为——当项目根目录下存在 go.mod 文件时,模块模式不再被自动激活;若当前工作目录或其任意父目录含有 go.mod,但未显式设置 GO111MODULE=on,go 命令将回退至 GOPATH 模式,导致依赖解析失败、go run 报错 no required module provides package,或 go list 无法识别本地模块。
Goland 启动失败的典型表现
IntelliJ IDEA 与 GoLand(2024.1 及更早版本)在打开含 go.mod 的项目时,默认复用系统环境变量。若终端中未设置 GO111MODULE=on,IDE 将继承该状态,进而触发以下问题:
- 项目结构视图显示“External Libraries”为空
- Run Configuration 中无法识别
main包 - 编辑器内大量红色波浪线,提示
cannot find package "xxx"
立即生效的修复方案
在项目根目录执行以下命令,强制初始化并验证模块状态:
# 确保模块已声明且启用
go env -w GO111MODULE=on
# 重新生成 go.mod(若缺失或损坏)
go mod init example.com/myapp # 替换为实际模块路径
# 验证模块解析是否正常
go list -m all # 应输出依赖树,而非报错
注意:
go env -w会持久化写入$HOME/go/env,影响全局行为;如需项目级隔离,建议在.bashrc/.zshrc中添加export GO111MODULE=on,或在 Goland 中配置 Settings → Go → GOROOT and GOPATH → Environment variables,显式添加GO111MODULE=on。
关键差异对比表
| 行为 | Go ≤1.22(auto 模式) | Go 1.23+(strict 模式) |
|---|---|---|
go.mod 存在但未设 GO111MODULE |
自动启用模块模式 | 强制使用 GOPATH 模式,忽略 go.mod |
go build 在模块根目录 |
成功编译 | 报错:build: cannot load xxx: cannot find module providing package xxx |
| Goland 自动检测模块 | ✅ 默认成功 | ❌ 需手动配置环境变量或升级插件 |
开发者应立即检查 CI/CD 脚本、Dockerfile 及 IDE 配置,统一注入 GO111MODULE=on,避免因隐式行为移除引发的构建雪崩。
第二章:深入理解GO111MODULE环境变量的演进与Goland集成逻辑
2.1 GO111MODULE=auto的历史成因与隐式行为陷阱(理论)+ 复现Go 1.22 vs 1.23下Goland新建项目module初始化差异(实践)
GO111MODULE=auto 是 Go 1.11 引入模块系统时的默认策略:仅当当前目录或父目录存在 go.mod 时启用模块模式,否则回退至 GOPATH 模式。这一设计本意是兼顾旧项目兼容性,却埋下隐式行为陷阱——路径中偶然存在的 go.mod(如上级 .git 目录外的遗留文件)会意外触发模块模式,导致依赖解析异常。
Goland 新建项目行为变迁
| Go 版本 | Goland 初始化行为 | 是否自动写入 go.mod |
|---|---|---|
| 1.22 | 仅在 GOPATH/src 外新建时显式提示 |
❌ 需手动 go mod init |
| 1.23 | 默认执行 go mod init <dir>(含 go.sum) |
✅ 自动初始化 |
# Go 1.23 下 Goland 创建项目后立即可见:
$ ls -A
go.mod go.sum main.go
此行为变更源于
cmd/go对GO111MODULE=auto的语义收紧:当工作目录不在GOPATH/src且无go.mod时,1.23 将主动创建模块以对齐“现代 Go 工程默认模块化”原则。
graph TD
A[用户新建项目] --> B{GO111MODULE=auto}
B -->|Go 1.22| C[检查当前/父目录 go.mod]
B -->|Go 1.23| D[额外检查是否在 GOPATH/src 内]
C --> E[无则沿用 GOPATH 模式]
D --> F[不在 GOPATH/src → 强制模块初始化]
2.2 Goland底层go env读取机制与IDE配置优先级链解析(理论)+ 使用godebug工具追踪IDE启动时module模式决策路径(实践)
GoLand 启动时通过多层环境上下文动态解析 go env,优先级链为:IDE 内置默认值 go.env 文件 GOROOT/GOPATH 自动探测。
环境读取触发时机
- IDE 初始化阶段调用
com.goide.gopath.GoPathEnvironment#computeGoEnv() - 每次项目加载或 SDK 切换时重新触发
优先级链示意表
| 优先级 | 来源 | 覆盖能力 | 示例变量 |
|---|---|---|---|
| 高 | go.env 文件 |
全局生效 | GO111MODULE=on |
| 中 | IDE Settings → Go → GOPATH | 仅当前项目 | GOPROXY=https://goproxy.cn |
| 低 | Shell 启动环境 | 依赖启动方式 | GOSUMDB=off |
追踪 module 模式决策路径(godebug 实践)
# 在 Goland 启动前注入调试钩子
godebug run --delve -- -gcflags="all=-N -l" \
-import-path=github.com/JetBrains/go-lang-plugin \
-func='com.goide.project.GoModuleSettings#detectMode'
该命令强制 Delve 在
GoModuleSettings.detectMode()入口设断点,可观察isInModuledProject()如何依据go.mod存在性、GO111MODULE值及GOROOT/src是否为空三重判定 module 模式。关键参数:-N -l禁用优化并保留行号,确保断点精准命中。
graph TD
A[IDE 启动] --> B{读取 go.env?}
B -->|存在| C[解析键值对注入 Env]
B -->|不存在| D[fallback 至 shell env]
C & D --> E[调用 go list -m -json]
E --> F[根据输出结构判定 module 模式]
2.3 go.mod文件缺失时Goland默认行为的源码级验证(理论)+ 通过JetBrains Platform Logs反向定位module auto-detection失败点(实践)
当项目根目录无 go.mod 时,GoLand 启用 module auto-detection 机制,其核心逻辑位于 com.goide.gomod.GoModuleManager#detectModules()。
日志触发关键路径
启用 Registry → ide.log.level.com.goide.gomod=DEBUG 后,可在 idea.log 中捕获:
[GoModuleManager] Trying to detect modules in /path/to/project
[GoModuleManager] No go.mod found at root — scanning subdirectories...
检测失败的典型日志特征
| 日志关键词 | 含义 | 关联源码位置 |
|---|---|---|
skipping non-Go directory |
跳过无 .go 文件的子目录 |
GoModuleDetector.kt:127 |
no module candidates found |
扫描完成但未命中有效模块 | GoModuleManager.kt:289 |
核心检测逻辑(简化版)
fun detectModules(projectDir: VirtualFile): List<GoModule> {
val candidates = projectDir.children
.filter { it.name == "go.mod" } // ① 优先找根目录
.ifEmpty {
projectDir.recursiveChildren()
.filter { it.name == "go.mod" && it.parent?.isDirectory == true }
}
return candidates.map { GoModule(it) } // ② 构建模块实例
}
逻辑分析:① 根目录
go.mod为首选;② 递归扫描仅在根缺失时触发,且要求go.mod父目录必须是合法目录(非 jar/vfs 虚拟路径),否则被静默忽略。参数projectDir必须为LocalFileSystem实例,否则recursiveChildren()返回空。
graph TD
A[Project Opened] --> B{go.mod exists at root?}
B -->|Yes| C[Load as single module]
B -->|No| D[Scan subdirs for go.mod]
D --> E{Found valid go.mod?}
E -->|Yes| F[Auto-import module]
E -->|No| G[Mark as GOPATH mode or unconfigured]
2.4 GOPATH模式残留对新项目构建的隐蔽干扰(理论)+ 清理Goland缓存+重置GOPATH相关配置并验证构建日志(实践)
隐蔽干扰源:go env 中的幽灵配置
即使使用 Go Modules,GO111MODULE=on 仍可能被 GOPATH 路径残留触发模块降级行为——尤其当项目根目录外存在 src/ 子目录时,go build 会误判为 GOPATH 模式。
清理与重置三步法
- 关闭 Goland → 删除
~/Library/Caches/JetBrains/GoLand*/(macOS)或%LOCALAPPDATA%\JetBrains\GoLand*\(Windows) - 执行:
go env -w GOPATH="" # 清空显式GOPATH go env -w GO111MODULE=on # 强制启用模块模式 go clean -modcache # 清理模块缓存go env -w持久化写入GOENV文件;-modcache防止旧版本依赖污染go build -x日志。
验证构建日志关键特征
| 日志片段 | 含义 |
|---|---|
cd $WORK |
使用临时工作区(Modules) |
mkdir -p $GOPATH/src |
出现即表明 GOPATH 残留激活 |
graph TD
A[执行 go build -x] --> B{日志含 GOPATH/src?}
B -->|是| C[回退检查 go env GOPATH]
B -->|否| D[构建路径为 $WORK]
2.5 Go SDK版本绑定与Goland内置go toolchain匹配策略(理论)+ 手动切换SDK并触发module初始化失败/成功双态对比实验(实践)
GoLand 启动时自动探测 GOROOT 并绑定首个可用 Go SDK;若项目 go.mod 声明 go 1.21,而当前 SDK 为 1.20.1,则 go mod init 将静默失败——不报错但不生成 go.sum。
SDK 版本冲突表现
- ✅ 成功态:SDK =
1.21.6+go.mod中go 1.21→go mod init写入go.sum且go list -m可见依赖树 - ❌ 失败态:SDK =
1.20.1+go 1.21→go mod init无输出、go.sum空、go list -m报go: inconsistent vendoring
实验验证命令
# 切换 SDK 后手动触发(需先在 Goland Settings → Go → GOROOT 中修改)
go env -w GOROOT="/usr/local/go-1.21.6"
go mod init example.com/test # 成功时立即生成 go.sum
逻辑分析:
go mod init依赖runtime.Version()返回的go字符串校验go.mod中声明版本。若GOROOT/bin/go version输出go1.20.1,而go.mod含go 1.21,工具链拒绝初始化 module —— 这是 Go 工具链的硬性语义约束,非 IDE 行为。
| SDK 版本 | go.mod 声明 | go mod init 结果 | go.sum 生成 |
|---|---|---|---|
| 1.20.1 | go 1.21 | 静默失败 | ❌ |
| 1.21.6 | go 1.21 | 成功 | ✅ |
第三章:Goland中Go Modules的显式启用与全局一致性配置
3.1 Settings → Go → Go Modules界面参数语义详解(理论)+ 启用“Enable Go modules integration”并验证go.mod自动生成时机(实践)
核心参数语义解析
IntelliJ IDEA 的 Settings → Go → Go Modules 界面中关键选项包括:
- ✅
Enable Go modules integration:启用后,IDE 将接管go mod生命周期管理; - 📁
Proxy URL:配置 GOPROXY(如https://goproxy.cn),影响依赖拉取路径; - ⚙️
Vendor directory:勾选时自动维护vendor/,与GOFLAGS=-mod=vendor行为对齐。
自动化触发机制
启用 Enable Go modules integration 后,go.mod 在以下任一操作时首次自动生成:
- 新建
.go文件并保存(含package main或非main包声明); - 执行
go get命令(IDE 内置终端或 External Tools 触发); - 添加 import 语句(如
import "github.com/gin-gonic/gin")并执行Optimize Imports。
验证流程示意
# 在 IDE 终端执行,触发模块初始化
go get github.com/spf13/cobra@v1.8.0
此命令将:① 检查当前目录是否存在
go.mod;② 若无,则调用go mod init <module-name>(默认推导为目录名);③ 自动写入require条目并下载依赖。IDE 实时监听go.mod变更并刷新依赖图谱。
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
Enable Go modules integration |
Boolean | false |
控制是否激活模块感知能力 |
Use GOPATH |
Boolean | false |
仅在禁用模块集成时生效 |
graph TD
A[用户编辑 .go 文件] --> B{已启用 Modules?}
B -->|Yes| C[检测 import / go get]
C --> D[调用 go mod init?]
D -->|首次| E[生成 go.mod + go.sum]
D -->|存在| F[更新 require / replace]
3.2 全局vs项目级go.mod生成策略选择依据(理论)+ 在空目录新建项目时强制触发go mod init并校验go.sum完整性(实践)
策略选择核心权衡维度
- 依赖隔离性:项目级
go.mod保障模块边界清晰,避免跨项目污染;全局无go.mod则丧失版本约束能力 - 可复现性:仅当
go.mod+go.sum同时存在且未被篡改,go build才能确保依赖哈希一致 - 工具链兼容性:
go list -m all、go mod graph等命令依赖项目级模块根目录识别
强制初始化与完整性校验实践
# 在空目录中创建可验证的模块起点
mkdir myapp && cd myapp
go mod init example.com/myapp # 显式指定module path,避免默认为"main"
go mod tidy # 触发依赖解析,生成初始 go.sum
go mod verify # 校验所有模块哈希是否匹配 go.sum 记录
go mod init必须显式传入 module path:若省略,Go 会退化为module main,导致后续go get无法正确解析相对导入;go mod verify是轻量级完整性断言,失败即退出非零码,适合 CI 前置检查。
初始化流程逻辑图
graph TD
A[空目录] --> B[go mod init <path>]
B --> C{go.sum 是否存在?}
C -->|否| D[go mod tidy → 生成 go.sum]
C -->|是| E[go mod verify]
D --> E
E --> F[校验通过:模块可信]
3.3 Go Modules代理与校验配置对首次项目加载的影响(理论)+ 配置GOPROXY+GOSUMDB后执行go list -m all验证依赖解析稳定性(实践)
Go 模块首次加载时,GOPROXY 与 GOSUMDB 共同决定依赖获取路径与完整性保障强度。未配置时,默认直连 GitHub 等源站,易受网络波动、限流及中间人篡改影响。
代理与校验协同机制
GOPROXY=https://proxy.golang.org,direct:优先经可信代理拉取模块,失败则回退本地构建(direct)GOSUMDB=sum.golang.org:强制校验go.sum中的哈希签名,拒绝未签名或签名不匹配的模块
验证依赖解析稳定性
# 设置环境变量(推荐写入 ~/.bashrc 或 .zshrc)
export GOPROXY="https://goproxy.cn,direct" # 国内加速
export GOSUMDB="sum.golang.org" # 保持官方校验
go list -m all
该命令触发完整模块图遍历:
✅ 从 GOPROXY 并行下载所有间接依赖(含版本元数据)
✅ 对每个模块 URL 查询 sum.golang.org 获取权威 checksum
✅ 若任一模块校验失败,立即终止并报错 checksum mismatch
| 配置组合 | 首次加载耗时 | 校验强度 | 网络容错性 |
|---|---|---|---|
GOPROXY=direct |
高(直连) | 弱 | 差 |
GOPROXY=...; GOSUMDB=off |
中 | 无 | 中 |
GOPROXY=...; GOSUMDB=... |
低(缓存+并行) | 强 | 优 |
graph TD
A[go list -m all] --> B{GOPROXY configured?}
B -->|Yes| C[Fetch module zip + go.mod from proxy]
B -->|No| D[Direct git clone]
C --> E[Query sum.golang.org for checksum]
E -->|Match| F[Cache & proceed]
E -->|Mismatch| G[Abort with error]
第四章:面向生产环境的Goland Go项目启动标准化迁移方案
4.1 新建项目前必备检查清单:SDK/Modules/Proxy/GOPATH四维校验(理论)+ 使用Goland Terminal执行check-go-env.sh脚本自动化诊断(实践)
新建 Go 项目前,环境一致性直接决定构建可复现性。需同步校验四个核心维度:
- SDK:
go version必须 ≥ 1.21(模块默认启用) - Modules:
GO111MODULE=on且GOPROXY配置有效 - Proxy:推荐
https://proxy.golang.org,direct - GOPATH:仅作 workspace 兼容参考,模块模式下非必需
# check-go-env.sh 核心片段
echo "→ GOPATH: $(go env GOPATH)"
go env GO111MODULE GOPROXY GOSUMDB | grep -E "(GO111MODULE|GOPROXY|GOSUMDB)"
该脚本在 Goland Terminal 中执行,自动捕获
go env输出并过滤关键变量,避免手动逐条验证遗漏。
| 维度 | 检查项 | 合规值示例 |
|---|---|---|
| SDK | go version |
go version go1.22.3 darwin/arm64 |
| Modules | GO111MODULE |
on |
| Proxy | GOPROXY |
https://proxy.golang.org,direct |
graph TD
A[启动 check-go-env.sh] --> B{GO111MODULE == on?}
B -->|否| C[报错:强制启用模块]
B -->|是| D[校验 GOPROXY 可达性]
D --> E[输出四维快照]
4.2 现有非Module项目一键升级为标准Module项目的IDE内操作流(理论)+ 右键项目→Convert to Go Module并修复import路径冲突(实践)
IDE内转换的本质机制
IntelliJ IDEA / GoLand 的 Convert to Go Module 并非黑盒操作,而是自动执行三步原子动作:
- 在项目根目录运行
go mod init <module-path>(默认推导为目录名,可编辑) - 扫描全部
.go文件,提取原始import路径 - 依据新 module path 重写所有 import 语句(如
import "utils"→import "myproject/utils")
关键冲突场景与修复策略
| 冲突类型 | 表现 | 修复方式 |
|---|---|---|
| 相对路径导入 | import "./config" |
手动改为 import "myproject/config" |
| 未声明的本地包 | import "models"(无对应目录) |
创建 models/ 目录或调整 import |
# 执行转换后建议立即验证
go mod tidy # 清理冗余依赖、补全缺失模块
go build ./... # 全量编译验证 import 可解析
此命令强制 Go 工具链重新解析所有 import 路径,并更新
go.mod。./...表示递归遍历当前目录下所有包,确保无隐藏路径错误。
转换流程逻辑(mermaid)
graph TD
A[右键项目 → Convert to Go Module] --> B[生成 go.mod + 初始化 module path]
B --> C[静态扫描 import 语句]
C --> D{是否含非标准路径?}
D -->|是| E[交互式提示重映射]
D -->|否| F[批量重写 import]
E --> F
F --> G[触发 go mod tidy 自动校准]
4.3 CI/CD流水线与Goland本地配置的Module行为对齐策略(理论)+ 在.github/workflows中复现Goland构建步骤并比对go env输出(实践)
为什么行为不一致?
Goland 默认启用 GO111MODULE=on 并使用 GOPROXY=https://proxy.golang.org,direct,而 GitHub Actions 默认继承系统环境(可能为空或过时)。模块解析路径、缓存位置、代理策略差异直接导致 go build 结果不一致。
关键对齐点
- 显式设置
GO111MODULE=on - 统一
GOPROXY与 Goland 配置一致 - 强制
GOSUMDB=sum.golang.org
复现构建步骤(.github/workflows/ci.yml 片段)
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.22'
- name: Print go env
run: go env | grep -E '^(GO111MODULE|GOPROXY|GOSUMDB|GOCACHE)'
该步骤输出可与 Goland 终端中
go env实时比对。若GOCACHE路径不同(如/home/runner/.cache/go-buildvs/Users/me/Library/Caches/go-build),需注意构建产物不可跨平台复用。
环境变量对齐对照表
| 变量 | Goland(macOS) | GitHub Actions(ubuntu-latest) |
|---|---|---|
GO111MODULE |
on |
on(setup-go v4 自动启用) |
GOPROXY |
https://proxy.golang.org,direct |
同左(需显式指定避免 fallback) |
GOSUMDB |
sum.golang.org |
off(默认!必须显式设为 sum.golang.org) |
graph TD
A[Goland IDE] -->|读取 go.env + project SDK 设置| B[Module 解析]
C[GitHub Actions] -->|依赖 workflow 中显式 env/step| B
B --> D{go mod download / build}
D --> E[一致的 checksum & cache key]
4.4 多模块工作区(Go Workspace)在Goland中的启用与调试支持(理论)+ 创建workspace.go并验证跨模块断点命中与代码跳转(实践)
Go 1.18 引入的 go.work 文件使多模块协同开发成为可能,Goland 自 2022.2 起原生支持 workspace 模式下的统一索引、跨模块跳转与断点穿透。
启用 workspace 模式
在项目根目录执行:
go work init
go work use ./module-a ./module-b
生成 go.work 后,Goland 自动识别为 workspace 并重建索引——无需手动配置。
验证跨模块能力
创建 workspace.go(仅作占位,不参与构建):
// workspace.go —— 触发 Goland workspace 模式激活
package main // 必须声明 package,否则 Goland 不加载 workspace 上下文
import _ "example.com/module-a" // 强制索引 module-a
import _ "example.com/module-b" // 强制索引 module-b
此文件不编译,但 Goland 依赖其
import _语句触发模块发现与符号联动。package main是关键,否则 workspace 模式无法激活。
断点与跳转行为对比
| 行为 | 单模块模式 | Workspace 模式 |
|---|---|---|
| Ctrl+Click 跳转 | ❌ 模块外失败 | ✅ 穿透至 module-b/internal/xxx.go |
| 在 module-b 函数内设断点 | ❌ 不命中 | ✅ 主模块调用时完整命中 |
graph TD
A[main.go 调用 module-b.Foo] --> B[Goland 解析 go.work]
B --> C[统一符号表构建]
C --> D[断点注册到 module-b/Foo]
D --> E[运行时命中并显示 module-b 源码]
第五章:后GO111MODULE=auto时代Goland Go工程化治理新范式
模块自动发现失效后的显式治理起点
自 Go 1.21 起,GO111MODULE=auto 默认行为被移除,Go 工具链强制要求模块上下文。这意味着在 Goland 中打开一个无 go.mod 的目录时,IDE 不再静默启用模块模式,而是明确提示“Project is not a Go module”。某电商中台团队曾因误将 internal/api 子目录单独导入 Goland,导致 go list -m all 报错 no modules found,CI 构建失败率上升 37%。他们随后在团队规范中强制要求:所有 Git 仓库根目录必须存在 go.mod,且 go mod init 必须指定权威模块路径(如 git.example.com/platform/order),禁止使用 . 或本地路径。
Goland 配置层的模块感知增强策略
Goland 2023.3+ 引入了 Project SDK → Go Modules 设置面板,支持为多模块工作区定义「主模块」与「依赖模块」关系。例如,一个微服务仓库包含 auth/, payment/, shared/ 三个子模块,团队通过 .idea/modules.xml 显式声明:
<component name="GoModulesSettings">
<option name="mainModulePath" value="$PROJECT_DIR$/go.mod" />
<option name="modules">
<list>
<module path="$PROJECT_DIR$/auth/go.mod" />
<module path="$PROJECT_DIR$/payment/go.mod" />
<module path="$PROJECT_DIR$/shared/go.mod" />
</list>
</option>
</component>
该配置使 Goland 的代码跳转、符号索引、测试运行器均按模块边界精准隔离,避免跨模块误引用未导出符号。
基于 go.work 的多模块协同开发实践
某云原生基础设施团队采用 go.work 统一管理 12 个独立发布模块(如 pkg/trace, cmd/agent, api/v2)。其 go.work 文件结构如下:
| 模块路径 | 版本状态 | 是否启用 replace |
|---|---|---|
./pkg/trace |
v0.8.3 |
否 |
./cmd/agent |
v1.2.0 |
是(指向本地 ../sdk) |
./sdk |
v0.5.0 |
否 |
配合 Goland 的 Go → Go Workspaces → Enable go.work 开关,开发者可在单个工作区中同时编辑 sdk 并实时验证 agent 对其的调用效果,go run ./cmd/agent 自动解析 go.work 中的 replace 规则,无需手动 go mod edit -replace。
CI 流水线中的模块一致性校验
团队在 GitHub Actions 中嵌入以下校验步骤,防止 go.mod 与实际依赖脱节:
# 校验所有 go.mod 是否可解析且无 dangling replace
find . -name "go.mod" -execdir sh -c '
go mod tidy -v 2>/dev/null || exit 1
go list -m all | grep -q "github.com/" || exit 1
' \;
同时,Goland 的 File → Settings → Tools → File Watchers 配置了 go mod vendor 监听器,当 go.sum 变更时自动触发 vendor 同步,确保 IDE 与 CI 使用完全一致的依赖快照。
依赖图谱可视化与腐化预警
使用 Goland 内置的 Diagrams → Show Diagram → Dependencies 功能,生成 order-service 模块的依赖拓扑图,并导出为 Mermaid:
graph TD
A[order-service] --> B[pkg/db]
A --> C[pkg/cache]
B --> D[github.com/jackc/pgx/v5]
C --> E[golang.org/x/exp/maps]
E -.->|deprecated| F["std: maps (Go 1.21+)"]
团队据此识别出 golang.org/x/exp/maps 已被标准库替代,推动全量迁移,减少第三方依赖面 12%。
工程化检查清单落地模板
团队将治理动作固化为 .goland-checklist.md,包含 7 类 23 项可执行条目,例如:
- ✅ 所有
go.mod中require行末尾无空格 - ✅
replace仅用于本地开发,CI 环境中GOEXPERIMENT=nomodulesum被禁用 - ✅
go.work中每个use路径必须为 Git 子模块或已git add的目录
该清单由 Goland 插件 Checklist Assistant 加载,每保存 go.mod 即触发逐项扫描并高亮失败项。
