3 步让 AI 写出更现代的 Go 代码:JetBrains 官方出的现代化指南,10 个立刻能用的对照
JetBrains 在 8 月初把 `JetBrains/go-modern-guidelines` 开源到了 GitHub(单日涨星 314),专门解决”AI 写出来的 Go 代码像 Go 1.0 时代”的问题。它教 AI 编程助手用 Go 1.21-1.27 的新特性——`max(a, b)`、`slices.Contains`、`cmp.Or`、`new(42)`、`errors.AsTypeT`——替换掉那些又长又啰嗦的老写法。今天这篇教程 3 步带大家用上这个指南,附 10 个”老写法 vs 新写法”对照。
准备清单
– Go 版本:1.21+(推荐 1.22+)
– AI 编程助手:Claude Code 或 Cursor(其他支持 plugin 的也行)
– 操作系统:任何(Go 跨平台)
– 时间:10-15 分钟
如果你项目还在 Go 1.18 / 1.19,强烈建议升级——Go 1.22 的性能提升对 AI 生成代码的体验影响很大。
第 1 步:安装 JetBrains 官方 marketplace
JetBrains 把这个 Skills 放在了 `JetBrains/go-modern-guidelines` 仓库。安装命令和上一篇 Claude Code 插件类似:
# 在 Claude Code 中执行
/plugin marketplace add JetBrains/go-modern-guidelines
然后安装具体插件:
/plugin install modern-go-guidelines@goland-claude-marketplace
安装成功后,Claude Code 在处理 Go 任务时会自动调用这个 Skill。也可以手动触发:
/modern-go-guidelines:use-modern-go
第 2 步:理解 Skills 是怎么工作的
JetBrains 的 Go Skills 工作机制是:
1. 检测项目版本:自动读取 `go.mod` 里的 `go 1.XX`
2. 匹配特性范围:只推荐项目实际支持的新特性
3. 替代老写法:把 AI 写出的”老 Go 代码”自动改写为现代写法
例如你的 `go.mod` 写的是 `go 1.22`,那 Skills 会推荐:
– `slices.Contains`(Go 1.21)
– `max/min`(Go 1.21)
– `cmp.Or`(Go 1.22)
但不会推荐:
– `errors.AsTypeT`(Go 1.26)
– `new(42)`(Go 1.26)
这样就避免了”代码写出来但编译不过”的问题。
第 3 步:10 个立刻能用的”老写法 → 新写法”对照
### 3.1 数值比较:`if-else` → `max(a, b)`
// 老写法(Go 1.0)
func max(a, b int) int {
if a > b {
return a
}
return b
}
// 新写法(Go 1.21+)
func max(a, b int) int {
return max(a, b) // 内置函数
}
### 3.2 切片查找:手写循环 → `slices.Contains`
// 老写法
func hasItem(list []string, target string) bool {
for _, v := range list {
if v == target {
return true
}
}
return false
}
// 新写法(Go 1.21+)
import "slices"
func hasItem(list []string, target string) bool {
return slices.Contains(list, target)
}
### 3.3 链式 nil 检查 → `cmp.Or`
// 老写法
func getValue(a, b, c *string) string {
if a != nil {
return *a
}
if b != nil {
return *b
}
if c != nil {
return *c
}
return ""
}
// 新写法(Go 1.22+)
import "cmp"
func getValue(a, b, c *string) string {
return cmp.Or(*a, *b, *c)
}
### 3.4 类型安全的 error 匹配:`errors.As` → `errors.AsTypeT`
// 老写法
var targetErr *MyError
if errors.As(err, &targetErr) {
// 处理 targetErr
}
// 新写法(Go 1.26+)
targetErr, ok := errors.AsType[*MyError](err)
if ok {
// 处理 targetErr
}
### 3.5 排序:`sort.Slice` → `slices.Sort`
// 老写法
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
// 新写法(Go 1.21+)
slices.SortFunc(users, func(a, b User) int {
return cmp.Compare(a.Age, b.Age)
})
### 3.6 复制:`copy(dst, src)` → `slices.Clone`
// 老写法
newSlice := make([]int, len(oldSlice))
copy(newSlice, oldSlice)
// 新写法(Go 1.21+)
newSlice := slices.Clone(oldSlice)
### 3.7 映射操作:手写循环 → `maps` 包
// 老写法:取 map 的所有 key
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
// 新写法(Go 1.21+)
import "maps"
keys := slices.Collect(maps.Keys(m))
### 3.8 字符串拼接:+ → `strings.Builder` 更高效
// 老写法(性能差)
result := ""
for _, s := range items {
result += s
}
// 新写法(性能好,Go 1.10+ 但常被 AI 忽略)
import "strings"
var b strings.Builder
for _, s := range items {
b.WriteString(s)
}
result := b.String()
### 3.9 取指针:`&value{}` → `new(T)`(Go 1.26)
// 老写法
p := &MyStruct{}
// 新写法(Go 1.26+)
p := new(MyStruct)
### 3.10 整数除法检查:`if x%2 == 0` → 专用 helper
// 老写法
if n%2 == 0 {
fmt.Println("even")
}
// 新写法(Go 1.22+ 仍未官方,但社区 helper)
// 等待 Go 1.28 加入 isEven/IsOdd
// 暂用:if n%2 == 0
注意:第 10 条还没有”完美替代”,是反例——告诉 AI 不要为了”现代化”而硬找不存在的 API。
一个能立刻验证 Skills 工作的 prompt
跑通 Skills 后,向 Claude Code 提一个 Go 任务:
# > 写一个函数,输入 []string,输出去重后的 []string
预期看到:
import "slices"
func dedup(items []string) []string {
seen := make(map[string]struct{}, len(items))
result := make([]string, 0, len(items))
for _, v := range items {
if _, ok := seen[v]; !ok {
seen[v] = struct{}{}
result = append(result, v)
}
}
return result
}
关键识别点:
– 使用 `slices`、`maps` 等 Go 1.21+ 标准库包
– 不出现手写的”for _, v := range … if v == target” 老循环
– 类型转换、nil 检查使用 `cmp.Or`、`errors.AsType` 等新 API
常见失败处理
1. Skills 没生效
AI 还在写老代码。检查:
# 确认插件已安装
/plugin list
# 强制调用一次
/modern-go-guidelines:use-modern-go "请优化这段代码..."
2. AI 推荐了项目不支持的特性
确认 `go.mod` 里的版本号。如果项目是 `go 1.20`,AI 不应该推荐 `slices.Contains`。把 `go.mod` 升级到对应版本:
go mod edit -go=1.22
go mod tidy
3. 现代写法反而可读性差
某些场景”老写法”更直观。例如嵌套 if-else 比 `cmp.Or` 更易读。Skills 不会强制现代化所有代码,它会”推荐”而不是”替换”。
进阶玩法
1. CI 集成:在 CI 流水线跑 `modernize` 静态分析工具,自动检测”可以现代化但还没现代化”的代码
2. 代码评审规则:把 Skills 推荐的写法加入团队 `CONTRIBUTING.md`
3. 培训新成员:用老/新写法的对照表培训新加入的 Go 工程师
配套工具:`modernize` analyzer
JetBrains 同步开源了一个 `modernize` 静态分析工具,安装方法:
go install golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest
然后在项目里跑:
modernize -fix ./...
它会自动把”可以现代化”的代码做 rewrite。建议先在分支上跑一次看看 diff,确认无误再合并。
📌 下周 LC 智趣厅 会出”用 modernize 工具批量改造老 Go 项目”的实战教程,关注不迷路。
— END —
LC 智趣厅 · 科技与生活的交点
ihygg.cn