Skip to content

golangci-lint - 强大的代码检查工具

golangci-lint 是一个快速的 Go 代码检查工具,集成了多个静态分析工具。

📋 概述

难度级别:⭐⭐⭐
考察范围:代码质量/静态分析
技术标签代码检查 静态分析 代码质量

问题分析

golangci-lint 是 Go 社区最流行的代码检查工具,集成了 50+ 个检查器,能够发现各种代码问题。

🎯 核心功能

1. 安装

bash
# 使用 Homebrew (macOS)
brew install golangci-lint

# 使用 curl
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2

# 使用 go install
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

2. 基本用法

bash
# 检查当前目录
golangci-lint run

# 检查指定目录
golangci-lint run ./pkg/...

# 检查所有包
golangci-lint run ./...

# 快速模式(只运行快速检查器)
golangci-lint run --fast

# 显示详细信息
golangci-lint run -v

# 自动修复
golangci-lint run --fix

📝 配置示例

.golangci.yml 配置文件

yaml
run:
  timeout: 5m
  tests: true
  skip-dirs:
    - vendor
  skip-files:
    - ".*\\.pb\\.go$"

linters:
  enable:
    - errcheck
    - gosimple
    - govet
    - ineffassign
    - staticcheck
    - unused
    - gofmt
    - goimports
  disable:
    - deadcode
    - varcheck

linters-settings:
  errcheck:
    check-type-assertions: true
    check-blank: true
  goconst:
    min-len: 2
    min-occurrences: 2
  gocritic:
    enabled-tags:
      - performance
      - style
    disabled-checks:
      - dupImport
  govet:
    check-shadowing: true
  misspell:
    locale: US

issues:
  exclude-rules:
    - path: _test\.go
      linters:
        - errcheck

🔧 常用检查器

1. 错误处理

go
// errcheck: 检查未处理的错误
func bad() {
    os.Open("file.txt")  // ❌ 错误未处理
}

func good() {
    file, err := os.Open("file.txt")  // ✅
    if err != nil {
        return err
    }
    defer file.Close()
}

2. 代码简化

go
// gosimple: 简化代码
func bad() {
    if x == true {  // ❌ 冗余
        // ...
    }
}

func good() {
    if x {  // ✅
        // ...
    }
}

3. 未使用代码

go
// unused: 检查未使用的代码
var unusedVar = 42  // ❌

func unusedFunc() {  // ❌
    // ...
}

4. 性能问题

go
// gocritic: 性能检查
func bad(s []int) {
    for i := range s {
        s[i] = i * 2  // ❌ 可能可以优化
    }
}

func good(s []int) {
    for i := 0; i < len(s); i++ {
        s[i] = i * 2  // ✅
    }
}

🎯 最佳实践

1. CI/CD 集成

yaml
# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: '1.21'
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v3
        with:
          version: latest

2. 预提交钩子

bash
#!/bin/sh
# .git/hooks/pre-commit

golangci-lint run
if [ $? -ne 0 ]; then
    echo "Linting failed. Please fix the issues."
    exit 1
fi

3. Makefile

makefile
.PHONY: lint
lint:
	golangci-lint run

.PHONY: lint-fix
lint-fix:
	golangci-lint run --fix

📊 检查器列表

检查器说明默认启用
errcheck检查未处理的错误
gosimple代码简化建议
govetgo vet 检查
ineffassign无效赋值
staticcheck静态分析
unused未使用代码
gofmt代码格式
goimports导入排序
gocritic代码审查
gosec安全检查
misspell拼写检查

🔍 常见问题

Q1: 如何忽略特定检查?

go
//nolint:errcheck
func ignoreError() {
    os.Open("file.txt")
}

//nolint:gocritic
func ignoreCritic() {
    // ...
}

Q2: 如何只运行特定检查器?

bash
golangci-lint run --enable=errcheck,govet

Q3: 如何查看所有检查器?

bash
golangci-lint linters

📖 参考资源

正在精进