ข้ามไปยังเนื้อหา

gofmt, go vet และ Linting

ในโลก TypeScript คุณต้องใช้เครื่องมือสามตัวแยกกันเพื่อครอบคลุมการจัดรูปแบบ รูปแบบที่เสี่ยงต่อบัก และ type error:

  • Prettier จัดรูปแบบโค้ดให้สม่ำเสมอ
  • ESLint ตรวจจับรูปแบบที่น่าสงสัยและบังคับใช้ convention
  • tsc (type-checker) รายงาน type error

Go ยุบทั้งหมดนี้ไว้ในเครื่องมือที่เป็นส่วนหนึ่งของการติดตั้ง Go มาตรฐาน เสริมด้วย linter จาก third-party (staticcheck หรือ golangci-lint) ที่ชุมชนใช้กันแทบทุกที่

gofmt (หรือ alias go fmt) เขียนทับไฟล์ source ของคุณ in-place เพื่อให้ตรงกับ Go style หนึ่งเดียว ต่างจาก Prettier ตรงที่ ไม่มี configuration ให้ปรับเลย ไม่มี .gofmtrc, ไม่มี printWidth, ไม่มี option singleQuote

Terminal window
# Format all packages in the module
go fmt ./...
# Preview what would change (dry-run)
gofmt -d .
# Write changes in-place
gofmt -w .

Editor ส่วนใหญ่รัน gofmt อัตโนมัติตอน save ถ้าใช้ VS Code แค่ติดตั้ง Go extension ตัวทางการ ก็ทำงานได้เลยโดยไม่ต้อง config อะไรเพิ่ม

TypeScript
// .prettierrc
{
"semi": true,
"singleQuote": false,
"printWidth": 100,
"tabWidth": 2,
"trailingComma": "es5"
}
// Run:
// npx prettier --write src/
Go
# No config file needed.
# Run:
go fmt ./...
# Or wire it into your editor's "format on save".
# The result is always the same regardless of who runs it.

go vet คือ static analyser ที่มาพร้อมกับ Go คอยหาบั๊กจริง ๆ ไม่ใช่แค่ปัญหา style เช่น:

  • การส่ง type ผิดให้ format string ของ fmt.Printf
  • โค้ดที่รันไปไม่ถึงหลัง return
  • struct tag ที่เขียนผิดรูปแบบ
  • การ copy mutex แบบ by value
Terminal window
go vet ./...

ให้นึกถึงเป็น subset ของ ESLint rule ที่จับความผิดพลาดจริง ๆ ไม่ใช่ preference ด้าน style

TypeScript
// ESLint (partial .eslintrc.json)
{
"rules": {
"no-unreachable": "error",
"no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "warn"
}
}
// Run:
// npx eslint src --ext .ts
Go
# No config needed.
go vet ./...
# Example output when something is wrong:
# ./main.go:12:2: Printf format %d has arg name of wrong type string

ทุกรุ่นล่าสุดเพิ่ม analyzer ที่ได้มาฟรี:

  • waitgroup (1.25) — wg.Add ที่วางอยู่ข้างใน goroutine ที่มันควรจะนับ
  • hostport (1.25) — fmt.Sprintf("%s:%d", host, port) พังกับ IPv6 ให้ใช้ net.JoinHostPort
  • stdversion — ตอนนี้ go test รันให้อัตโนมัติ (1.27): เตือนเมื่อใช้ symbol ใน stdlib ที่ใหม่กว่าบรรทัด go ใน go.mod

--fix ของ ESLint เขียนโค้ดใหม่ให้ตรง idiom รุ่นล่าสุด Go 1.26 สร้าง go fix ขึ้นใหม่บน analysis framework เดียวกับ go vet พร้อมชุด modernizer: loop ที่ควรเป็น for range n, Min/Max ที่เขียนเอง → built-in, wg.Add(1); go f() → wg.Go(f) (ชื่อ waitgroup ใน 1.26 เปลี่ยนชื่อเป็น waitgroupgo ใน 1.27), sort.Slice → slices.SortFunc และอื่น ๆ

Terminal window
go fix ./... # apply every modernizer
go fix -diff ./... # preview as a diff first

คนเขียนไลบรารีก็ mark function ด้วย //go:fix inline ได้ เพื่อให้ผู้เรียกถูก migrate ไปใช้ตัวแทนอัตโนมัติ — เทียบเท่า codemod ที่ ship มากับ package ในโลก JS

ของแถมจาก go doc ใน 1.27 อีกสองอย่าง: go doc example.com/[email protected] ดู doc ของ version ที่ระบุ และ go doc -ex pkg แสดงรายการ example ที่รันได้

go vet จับบักที่ชัดเจนที่สุด ส่วนการตรวจที่ครอบคลุมกว่า — exports ที่ไม่ถูกใช้, การใช้ deprecated API, โค้ดที่เขียนให้สั้นลงได้ — ชุมชนจะพึ่ง:

  • staticcheck (honnef.co/go/tools) — linter แบบ focused ที่มี signal สูง
  • golangci-lint — meta-linter ที่รัน linter หลายตัวพร้อมกัน รวมถึง staticcheck, errcheck, gosimple และอื่น ๆ
Terminal window
# Install staticcheck
go install honnef.co/go/tools/cmd/staticcheck@latest
# Run it
staticcheck ./...
# Or use golangci-lint (recommended for CI)
# Install: https://golangci-lint.run/usage/install/
golangci-lint run ./...

.golangci.yml เริ่มต้นที่แนะนำ:

linters:
enable:
- staticcheck
- errcheck
- gosimple
- unused
linters-settings:
staticcheck:
go: "1.27"

รันคำสั่งพวกนี้ใน terminal หลังติดตั้ง golangci-lint ตัว linter ไม่มีเวอร์ชันที่รันบน browser

คุณสร้างไฟล์อะไรเพื่อกำหนดค่า style ของ gofmt?
เครื่องมือไหนที่เทียบเท่ากับ bug-detection rules ของ ESLint ใน Go (ไม่ใช่ style)?
`go fmt ./...` ทำอะไร?
golangci-lint อธิบายได้ดีที่สุดว่า: