Golangci-lint:你的 Go 守护者,抵御代码异味

发布: (2026年3月23日 GMT+8 12:41)
4 分钟阅读
原文: Dev.to

Source: Dev.to

为什么不直接使用 go vet

go vet 只能捕获一小部分问题——错误的 printf 格式字符串、不可达代码、错误的结构体标签。它只是一个基线检查,而不是完整的 linter 套件。golangci-lint 在一次运行中执行数十个 linter,并统一输出结果。它之所以快,是因为复用了 Go 的构建缓存并且并发运行 linter。

安装

# Homebrew
brew install golangci-lint

# Go install (pinned version)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

使用 golangci-lint --version 验证。当前使用的是 v2 配置格式(version: "2")。

入门配置

在项目根目录创建 .golangci.yml。先使用 default: standard,再添加能够捕获真实问题的 linter:

version: "2"
linters:
  default: standard
  enable:
    - bodyclose       # unclosed HTTP response bodies
    - contextcheck    # context.Context misuse
    - errname         # error type naming (ErrFoo)
    - errorlint       # unwrapped errors break errors.Is/As
    - exhaustive      # missing switch/map cases
    - gocognit        # cognitive complexity
    - gosec           # security issues
    - nestif          # deeply nested ifs
    - noctx           # HTTP requests without context
    - prealloc        # slice preallocation hints
    - unconvert       # unnecessary type conversions
    - unparam         # unused function parameters
  settings:
    gocognit:
      min-complexity: 20
    errcheck:
      check-type-assertions: true
  exclusions:
    presets:
      - comments
      - common-false-positives
    rules:
      - linters: [funlen, goconst, gosec, noctx]
        path: _test\.go

这样在第一天就能得到有意义的反馈,而不会被大量噪音淹没。

值得了解的 Linters

gosec

标记安全问题——SQL 注入、弱加密、硬编码凭证。在实际配置中你需要排除误报:

gosec:
  excludes:
    - G404  # math/rand is fine for non-crypto use
    - G101  # config keys flagged as credentials

depguard

阻止项目中出现不希望使用的导入。可用于强制执行架构边界:

depguard:
  rules:
    deprecated:
      deny:
        - pkg: io/ioutil
          desc: "deprecated since Go 1.16; use io and os"
    weak_crypto:
      deny:
        - pkg: crypto/md5
          desc: "use crypto/sha256 or crypto/sha512"

forbidigo

禁止特定函数调用。常用于强制使用结构化日志而不是 fmt.Print

forbidigo:
  forbid:
    - pattern: '^fmt\.Print'
      msg: "Use structured logging instead of fmt.Print"
    - pattern: 'http\.DefaultClient'
      msg: "Create a client with explicit timeouts"

运行

# Lint the whole project
golangci-lint run

# Lint with auto-fix where possible
golangci-lint run --fix

# Lint only changed files (fast CI feedback)
golangci-lint run --new-from-rev=HEAD~1

将其添加到你的 Taskfile

如果你使用 Task,可以添加一个 lint 任务:

lint:
  desc: Run golangci-lint
  cmds:
    - golangci-lint run ./...

然后执行 task lint 即可运行完整的检查套件。在 CI 中使用同样的命令——本地检查的内容就是 CI 强制执行的内容。

小步起步

第一天并不需要 70 个 linter。先使用 default: standard 加上上面列出的 12 个。当你逐步修复初始发现的问题后,可以再启用更多。配置文件受版本控制,整个团队都能保持一致。

0 浏览
Back to Blog

相关文章

阅读更多 »

关于静态分析 + LLM

抱歉,我没有看到需要翻译的具体文本。请提供要翻译的摘录或摘要内容,我会为您翻译成简体中文。