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 新写法”对照。

3 步让 AI 写出更现代的 Go 代码:JetBrains 官方出的现代化指南,10 个立刻能用的封面

准备清单

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

Scroll to Top
微信公众号:LC智趣厅

扫码关注微信公众号
LC智趣厅