golang-naming

작성자: samber

Go (Golang) 네이밍 규칙 — 패키지, 생성자, 구조체, 인터페이스, 상수, 열거형, 오류, 불리언, 리시버, 게터/세터, 함수형 옵션, 약어, 테스트 함수, 서브테스트 이름을 다룹니다. 새 Go 코드를 작성하거나, 코드 리뷰 또는 리팩토링 시, 네이밍 대안(New vs NewTypeName, isConnected vs connected, ErrNotFound vs NotFoundError, iota 0에서 StatusReady vs StatusUnknown) 중 선택하거나, Go 패키지 이름(utils/helpers 안티패턴)을 논의할 때 이 스킬을 사용하세요.

npx skills add https://github.com/samber/cc-skills-golang --skill golang-naming

Community default. A company skill that explicitly supersedes samber/cc-skills-golang@golang-naming skill takes precedence.

Go Naming Conventions

Go favors short, readable names. Capitalization controls visibility — uppercase is exported, lowercase is unexported. All identifiers MUST use MixedCaps, NEVER underscores.

"Clear is better than clever." — Go Proverbs

"Design the architecture, name the components, document the details." — Go Proverbs

To ignore a rule, just add a comment to the code.

Quick Reference

ElementConventionExample
Packagelowercase, single word, _test suffix OK for test filesjson, http, tabwriter, http_test
Filelowercase, underscores OKuser_handler.go
Exported nameUpperCamelCaseReadAll, HTTPClient
UnexportedlowerCamelCaseparseToken, userCount
Interfacemethod name + -erReader, Closer, Stringer
StructMixedCaps nounRequest, FileHeader
ConstantMixedCaps (not ALL_CAPS)MaxRetries, defaultTimeout
Receiver1-2 letter abbreviationfunc (s *Server), func (b *Buffer)
Error variableErr prefixErrNotFound, ErrTimeout
Error typeError suffixPathError, SyntaxError
ConstructorNew (single type) or NewTypeName (multi-type)ring.New, http.NewRequest
Boolean fieldis, has, can prefix on fields and methodsisReady, IsConnected()
Test functionTest + function nameTestParseToken
Acronymall caps or all lowerURL, HTTPServer, xmlParser
Variant: contextWithContext suffixFetchWithContext, QueryContext
Variant: in-placeIn suffixSortIn(), ReverseIn()
Variant: errorMust prefixMustParse(), MustLoadConfig()
Option funcWith + field nameWithPort(), WithLogger()
Enum (iota)type name prefix, zero-value = unknownStatusUnknown at 0, StatusReady
Named returndescriptive, for docs only(n int, err error)
Error stringlowercase (incl. acronyms), no punctuation"image: unknown format", "invalid id"
Import aliasshort, only on collisionmrand "math/rand", pb "app/proto"
Format funcf suffixErrorf, Wrapf, Logf
Test table fieldsgot/expected prefixesinput string, expected int

MixedCaps

All Go identifiers MUST use MixedCaps (or mixedCaps). NEVER use underscores in identifiers — the only exceptions are test function subcases (TestFoo_InvalidInput), generated code, and OS/cgo interop. This is load-bearing, not cosmetic — Go's export mechanism relies on capitalization, and tooling assumes MixedCaps throughout.

// ✓ Good
MaxPacketSize
userCount
parseHTTPResponse

// ✗ Bad — these conventions conflict with Go's export mechanism and tooling expectations
MAX_PACKET_SIZE   // C/Python style
max_packet_size   // snake_case
kMaxBufferSize    // Hungarian notation

Avoid Stuttering

Go call sites always include the package name, so repeating it in the identifier wastes the reader's time — http.HTTPClient forces parsing "HTTP" twice. A name MUST NOT repeat information already present in the package name, type name, or surrounding context.

// Good — clean at the call site
http.Client       // not http.HTTPClient
json.Decoder      // not json.JSONDecoder
user.New()        // not user.NewUser()
config.Parse()    // not config.ParseConfig()

// In package sqldb:
type Connection struct{}  // not DBConnection — "db" is already in the package name

// Anti-stutter applies to ALL exported types, not just the primary struct:
// In package dbpool:
type Pool struct{}        // not DBPool
type Status struct{}      // not PoolStatus — callers write dbpool.Status
type Option func(*Pool)   // not PoolOption

Frequently Missed Conventions

These conventions are correct but non-obvious — they are the most common source of naming mistakes:

Constructor naming: When a package exports a single primary type, the constructor is New(), not NewTypeName(). This avoids stuttering — callers write apiclient.New() not apiclient.NewClient(). Use NewTypeName() only when a package has multiple constructible types (like http.NewRequest, http.NewServeMux).

Boolean struct fields: Unexported boolean fields MUST use is/has/can prefix — isConnected, hasPermission, not bare connected or permission. The exported getter keeps the prefix: IsConnected() bool. This reads naturally as a question and distinguishes booleans from other types.

Error strings are fully lowercase — including acronyms. Write "invalid message id" not "invalid message ID", because error strings are often concatenated with other context (fmt.Errorf("parsing token: %w", err)) and mixed case looks wrong mid-sentence. Sentinel errors should include the package name as prefix: errors.New("apiclient: not found").

Enum zero values: Always place an explicit Unknown/Invalid sentinel at iota position 0. A var s Status silently becomes 0 — if that maps to a real state like StatusReady, code can behave as if a status was deliberately chosen when it wasn't.

Subtest names: Table-driven test case names in t.Run() should be fully lowercase descriptive phrases: "valid id", "empty input" — not "valid ID" or "Valid Input".

Detailed Categories

For complete rules, examples, and rationale, see:

  • Packages, Files & Import Aliasing — Package naming (single word, lowercase, no plurals), file naming conventions, import alias patterns (only use on collision to avoid cognitive load), and directory structure.

  • Variables, Booleans, Receivers & Acronyms — Scope-based naming (length matches scope: i for 3-line loops, longer names for package-level), single-letter receiver conventions (s for Server), acronym casing (URL not Url, HTTPServer not HttpServer), and boolean naming patterns (isReady, hasPrefix).

  • Functions, Methods & Options — Getter/setter patterns (Go omits Get so user.Name() reads naturally), constructor conventions (New or NewTypeName), named returns (for documentation only), format function suffixes (Errorf, Wrapf), and functional options (WithPort, WithLogger).

  • Types, Constants & Errors — Interface naming (Reader, Closer suffix with -er), struct naming (nouns, MixedCaps), constants (MixedCaps, not ALL_CAPS), enums (type name prefix like StatusReady), sentinel errors (ErrNotFound variables), error types (PathError suffix), and error message conventions (lowercase, no punctuation).

  • Test Naming — Test function naming (TestFunctionName), table-driven test field conventions (input, expected), test helper naming, and subcase naming patterns.

Common Mistakes

MistakeFix
ALL_CAPS constantsGo reserves casing for visibility, not emphasis — use MixedCaps (MaxRetries)
GetName() getterGo omits Get because user.Name() reads naturally at call sites. But Is/Has/Can prefixes are kept for boolean predicates: IsHealthy() bool not Healthy() bool
Url, Http, Json acronymsMixed-case acronyms create ambiguity (HttpsUrl — is it Https+Url?). Use all caps or all lower
this or self receiverGo methods are called frequently — use 1-2 letter abbreviation (s for Server) to reduce visual noise
util, helper packagesThese names say nothing about content — use specific names that describe the abstraction
http.HTTPClient stutteringPackage name is always present at call site — http.Client avoids reading "HTTP" twice
user.NewUser() constructorSingle primary type uses New()user.New() avoids repeating the type name
connected bool fieldBare adjective is ambiguous — use isConnected so the field reads as a true/false question
"invalid message ID" errorError strings must be fully lowercase including acronyms — "invalid message id"
StatusReady at iota 0Zero value should be a sentinel — StatusUnknown at 0 catches uninitialized values
"not found" error stringSentinel errors should include the package name — "mypackage: not found" identifies the origin
userSlice type-in-nameTypes encode implementation detail — users describes what it holds, not how
Inconsistent receiver namesSwitching names across methods of the same type confuses readers — use one name consistently
snake_case identifiersUnderscores conflict with Go's MixedCaps convention and tooling expectations — use mixedCaps
Long names for short scopesName length should match scope — i is fine for a 3-line loop, userIndex is noise
Naming constants by valueValues change, roles don't — DefaultPort survives a port change, Port8080 doesn't
FetchCtx() context variantWithContext is the standard Go suffix — FetchWithContext() is instantly recognizable
sort() in-place but no InReaders assume functions return new values. SortIn() signals mutation
parse() panicking on errorMustParse() warns callers that failure panics — surprises belong in the name
Mixing With*, Set*, Use*Consistency across the codebase — With* is the Go convention for functional options
Plural package namesGo convention is singular (net/url not net/urls) — keeps import paths consistent
Wrapf without f suffixThe f suffix signals format-string semantics — Wrapf, Errorf tell callers to pass format args
Unnecessary import aliasesAliases add cognitive load. Only alias on collision — mrand "math/rand"
Inconsistent concept namesUsing user/account/person for the same concept forces readers to track synonyms — pick one name

Enforce with Linters

Many naming convention issues are caught automatically by linters: revive, predeclared, misspell, errname. See samber/cc-skills-golang@golang-lint skill for configuration and usage.

Cross-References

  • → See samber/cc-skills-golang@golang-code-style skill for broader formatting and style decisions
  • → See samber/cc-skills-golang@golang-structs-interfaces skill for interface naming depth and receiver design
  • → See samber/cc-skills-golang@golang-lint skill for automated enforcement (revive, predeclared, misspell, errname)

samber의 다른 스킬

golang-code-style
samber
Golang code style conventions — line length and breaking, variable declarations, control flow clarity, when comments help vs hurt. Use when writing or reviewing Go code, asking about style or clarity, or establishing project coding standards. Not for naming conventions (→ See `samber/cc-skills-golang@golang-naming` skill), linter configuration (→ See `samber/cc-skills-golang@golang-lint` skill), or doc comments (→ See `samber/cc-skills-golang@golang-documentation` skill).
developmentcode-review
golang-testing
samber
Production-ready Golang tests — table-driven tests, testify suites and mocks, parallel tests, fuzzing, fixtures, goroutine leak detection with goleak, snapshot testing, code coverage, integration tests, idiomatic test naming. Use when writing or reviewing Go tests, choosing a testing approach, setting up Go test CI, or debugging flaky/slow tests. For testify-specific APIs see `samber/cc-skills-golang@golang-stretchr-testify`; for measurement methodology see...
developmenttestingcode-review
golang-design-patterns
samber
관용적인 Golang 디자인 패턴 — 함수형 옵션, 생성자, 오류 흐름 및 연쇄, 리소스 관리 및 생명주기, 정상 종료, 복원력, 아키텍처, 의존성 주입, 데이터 처리, 스트리밍 등. 아키텍처 패턴을 명시적으로 선택할 때, 함수형 옵션을 구현할 때, 생성자 API를 설계할 때, 정상 종료를 설정할 때, 복원력 패턴을 적용할 때, 또는 특정 문제에 맞는 관용적인 Go 패턴을 질문할 때 적용하세요.
developmentdesigncode-review
golang-error-handling
samber
Idiomatic Golang error handling — creation, wrapping with %w, errors.Is/As, errors.Join, custom error types, sentinel errors, panic/recover, the single handling rule, structured logging with slog, HTTP request logging middleware, and samber/oops for production errors. Built to make logs usable at scale with log aggregation 3rd-party tools. Apply when creating, wrapping, inspecting, or logging errors in Go code. For samber/oops specifics → See `samber/cc-skills-golang@golang-samber-oops`...
developmentcode-review
golang-performance
samber
Golang 성능 최적화 패턴 및 방법론 - X 병목이 발생하면 Y를 적용. 할당 감소, CPU 효율성, 메모리 레이아웃, GC 튜닝, 풀링, 캐싱, 핫패스 최적화를 다룹니다. 프로파일링이나 벤치마크에서 병목이 확인되어 이를 해결할 적절한 최적화 패턴이 필요할 때 사용합니다. 또한 성능 코드 리뷰 시 개선 사항이나 빠른 성능 향상을 식별하는 데 도움이 될 벤치마크를 제안할 때 사용합니다. 측정 방법론에는 해당하지 않습니다(→...
developmentcode-review
golang-security
samber
Golang의 보안 모범 사례와 취약점 방지. 인젝션(SQL, 명령어, XSS), 암호화, 파일 시스템 안전, 네트워크 보안, 쿠키, 비밀 관리, 메모리 안전, 로깅을 다룹니다. 보안을 위해 Go 코드를 작성, 검토 또는 감사할 때, 또는 암호화, I/O, 비밀 관리, 사용자 입력 처리, 인증과 관련된 위험한 코드 작업 시 적용하세요. 보안 도구 구성도 포함됩니다.
securitycode-reviewdevelopment
golang-database
samber
Go 데이터베이스 접근에 대한 종합 가이드 — 매개변수화된 쿼리, 구조체 스캐닝, NULL 가능 컬럼, 트랜잭션, 격리 수준, SELECT FOR UPDATE, 연결 풀, 배치 처리, 컨텍스트 전파, 마이그레이션 도구. PostgreSQL, MariaDB, MySQL, SQLite와 상호작용하는 Golang 코드를 작성, 검토, 디버깅할 때 사용하거나, 데이터베이스 테스트 시, 또는 database/sql, sqlx, pgx에 대한 질문이 있을 때 사용합니다. 데이터베이스 스키마나 마이그레이션 SQL은 생성하지 않습니다.
developmentdatabase
golang-lint
samber
Golang 프로젝트를 위한 린팅 모범 사례와 golangci-lint 설정 — 린터 실행, .golangci.yml 구성, nolint 지시어로 경고 억제, 린트 출력 해석, 린터 선택. golangci-lint를 구성할 때, 린트 경고나 nolint 억제에 대해 질문할 때, 코드 품질 도구를 설정할 때, 또는 린터를 선택할 때 사용합니다. 또한 사용자가 golangci-lint, go vet, staticcheck, revive를 언급할 때 사용합니다.
developmentcode-reviewtesting