agentleFS
h2coneh2cone/agent-packs/skills/effective-go/SKILL.md

effective-go

Skill0 starsChanged 25 days agoMITView on GitHub

Knowledge base from \"Effective Go\" by The Go Authors, plus a 1.18–1.22 syntax/stdlib supplement. Use when writing idiomatic Go: formatting, naming, control structures, functions, data, concurrency, errors, embedding; or when choosing modern replacements (any, errors.Is, slices, range-over-int, loopvar, ServeMux patterns).

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. caijiatao/skills★ 1same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository9 other files it gives its agents.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Writing or editing Go: - read references/modern.md first.

    line 15
  2. Very specific:

    With a topic: - ask about slices, channels, interfaces, defer, etc..

    line 17
  3. Very specific:

    With a chapter: - ask for ch09 (Data) or ch15 (Concurrency).

    line 18
  4. Distinctive:

    Browse: - ask "what chapters do you have?" to see the full index.

    line 19
  5. Distinctive:

    When you ask about a topic not in Core Frameworks below, I read the relevant chapter file before answering.

    line 21
  6. Very specific:

    gofmt is the single source of truth for formatting: Never hand-align; run gofmt (file) or go fmt (package).

    line 29

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- argument-hint: [topic, framework name, or chapter number] -->

Effective Go

Author: The Go Authors (Go team) | Length: ~33 pages / ~16.5k words | Sections: 17 | Generated: 2026-08-06

Source: go.dev/doc/effective_go. The chapters distill the 2009 document (core language, not generics/modules). references/modern.md covers the 1.18–1.22 syntax and stdlib that agents otherwise emit from outdated training data.

How to Use This Skill

  • Writing or editing Go - read references/modern.md first. Apply each rule whose Since is ≤ the target package's owning go.mod version and whose preconditions are met; go.work does not override that language version. Those rules win over older snippets in the chapters.
  • Without arguments - load core frameworks below. Do not load all 17 chapters.
  • With a topic - ask about slices, channels, interfaces, defer, etc.; load only the matching chapter (and modern.md when the topic is syntax/stdlib).
  • With a chapter - ask for ch09 (Data) or ch15 (Concurrency); load that chapter file.
  • Browse - ask "what chapters do you have?" to see the full index.

When you ask about a topic not in Core Frameworks below, I read the relevant chapter file before answering.


Core Frameworks & Mental Models

Share memory by communicating. Go's slogan: "Do not communicate by sharing memory; instead, share memory by communicating." Pass shared values on channels; only one goroutine owns a value at a time, so data races can't occur by design. Prefer this over mutex-guarded variables; reserve mutexes for cases like reference counts. (Ch 15)

gofmt is the single source of truth for formatting. Never hand-align; run gofmt (file) or go fmt (package). Tabs indent; no line-length limit; no parentheses on if/for/switch. If gofmt's output looks wrong, restructure the code - don't work around it. (Ch 3)

Capitalization is visibility. First letter upper-case = exported; lower-case = package-private. This is semantic, not stylistic. (Ch 5)

Name for how it reads at the call site. Package names: lower-case, single word, match the directory base, favor brevity. Don't stutter - bufio.Reader not BufReader; ring.New when one exported type; once.Do(setup) not DoOrWaitUntilDone. Getters drop Get (Owner for field owner); setters use Set (SetOwner). One-method interfaces are method+-er (Reader, Writer); reuse canonical names/signatures (String, not ToString). Use MixedCaps, never underscores. (Ch 5)

Keep the happy path down the page. if/switch take an init statement (if err := f(); err != nil). When a guard body ends in return/break/continue, drop the else - eliminate error cases as they arise. := lets one err flow through a chain of guards in the same scope. (Ch 7)

for is the only loop; switch is a condition ladder. for init; cond; post {} / for cond {} / for {}. On Go 1.22+, for i := range n replaces for i := 0; i < n; i++. range also iterates collections and decodes strings to runes; drop the second value for key-only, use _ for value-only. On 1.22+, loop variables declared with := are per-iteration; omit redundant v := v copies for those variables. With =, keep a copy or pass the value as a goroutine argument when capturing an iteration's value. switch {} (no expression) switches on true - the idiomatic if-else-if. No fallthrough; comma-separated cases. Label a loop and break Loop to exit it from inside a switch. Type switch: switch t := x.(type) on any, not interface{}. (Ch 7, modern.md)

Multiple returns replace in-band errors and out-params. Return (value, error). Named result parameters document the return and enable naked return. (Ch 8)

defer guarantees cleanup. defer f.Close() right after os.Open - never forgets a close on any return path, and keeps release next to acquire. Deferred args evaluate at the defer; calls run LIFO. It's function-scoped, not block-scoped - that's its power. (Ch 8)

new zeros and returns a pointer; make initializes and returns a value. make is for slices/maps/channels only. Design types whose zero value is usable (bytes.Buffer, sync.Mutex) - it composes transitively. Construct with composite literals (&File{fd: fd}; &File{} == new(File)). Prefer slices over arrays. append returns a (possibly reallocated) slice - always reassign (x = append(x, ...)). Map lookups return the zero value for missing keys; use the comma-ok idiom when absence matters. (Ch 9)

Master fmt and avoid the String() recursion trap. %v/%+v/%#v/%T/%q; define String() string (the Stringer interface) to control formatting. A String() that calls Sprintf("%s", m) on the same string-like type recurses forever - convert to string first or use a non-string verb. (Ch 9, 10)

iota generates constant families; init verifies/registers. const ( _ = iota; KB = 1<<(10*iota); MB ... ). init runs after vars and imports - use it for sanity checks and registration. (Ch 10)

Pointer receiver to mutate or satisfy interfaces. Value methods run on values and pointers; pointer methods run only on pointers (the compiler auto-takes the address of addressable values). A *T receiver is how *ByteSlice satisfies io.Writer. (Ch 11)

Interfaces are implicit, small, and capability-shaped. A type satisfies an interface by implementing its methods - no implements. Convert between same-underlying types to reuse method sets (no copy). Type-assert with comma-ok (v, ok := x.(T)); never bare. When a type only implements an interface, export the interface and return it from the constructor. Any type with methods - struct, int, channel, function - can satisfy one; http.HandlerFunc(f) adapts a function into an http.Handler. (Ch 12)

_ makes intent explicit. Discard unwanted returns, do presence-only map checks, silence unused decls temporarily, import for side effects (import _ "pkg"), and enforce conformance at compile time (var _ I = (*T)(nil)). Never use it to discard an error. (Ch 13)

Embedding is composition, not inheritance. Embed a type to promote its methods and satisfy interfaces for free (io.ReadWriter = Reader + Writer; bufio.ReadWriter embeds *Reader/*Writer). The promoted method's receiver is the inner type - no virtual dispatch. Reach in via the type name to refine. (Ch 14)

Channels synchronize; buffered channels limit throughput. Unbuffered = synchronous handshake. make(chan int, N) is a semaphore of capacity N. Gate goroutine creation (or use a fixed pool) to bound resources - don't just limit running count. Channels are first-class - embed a reply channel for parallel demux. select/default gives non-blocking ops (leaky-buffer free lists). Concurrency (structure) ≠ parallelism (speed). (Ch 15)

Return descriptive errors; reserve panic for the unrecoverable. Implement error with a richer struct (PathError{Op, Path, Err}) when callers may inspect cause. Inspect with errors.Is / errors.As (wrap with %w); do not use err == target or a bare type-assert on a wrapped error. recover works only in deferred functions - isolate failing goroutines or convert internal panics to errors at the package boundary. Never expose panics to clients. (Ch 16, modern.md)


Chapter Index

#TitleKey Frameworks
ch01IntroductionThink from a Go perspective, not by translation
ch02ExamplesStandard library as reference implementation
ch03Formattinggofmt, tabs, no line limit, no parens
ch04Commentary// vs /* */, doc comments precede decl
ch05NamesCapitalization=visibility, no stutter, Owner not GetOwner, -er interfaces, MixedCaps
ch06SemicolonsAutomatic insertion, brace-on-same-line
ch07Control structuresif-init, omit else, for/range/range n, switch{}, type switch, labeled break
ch08FunctionsMultiple returns, named results, defer
ch09Datanew/make, composite literals, slices, append, maps, comma-ok, fmt, Stringer
ch10InitializationConstants, iota, runtime var, init
ch11MethodsPointer vs value receiver, methods on any named type
ch12InterfacesImplicit satisfaction, conversion, type switch/assertion, HandlerFunc
ch13The blank identifierDiscard returns, side-effect import, compile-time interface check
ch14EmbeddingInterface/struct embedding, method promotion, not subclassing
ch15ConcurrencyShare by communicating, goroutines, channels, semaphore, fixed pool, leaky buffer
ch16Errorserror interface, PathError, errors.Is/As, panic/recover, panic-to-error boundary
ch17A web serverflag, ServeMux patterns, HandlerFunc, ListenAndServe, template.Must

Topic Index

  • append -> ch09
  • blank identifier (_) -> ch07, ch09, ch10, ch13
  • buffered channel / semaphore -> ch15
  • channel -> ch15
  • comma-ok idiom -> ch09, ch12
  • composite literal -> ch09
  • concurrency vs parallelism -> ch15
  • constant / iota -> ch10
  • conversion -> ch12
  • defer -> ch08, ch16
  • doc comment -> ch04
  • embedding -> ch14
  • error -> ch16, modern.md
  • errors.Is / errors.As -> modern.md
  • exported / capitalization -> ch05
  • fmt verbs -> ch09
  • for / range / range-over-int -> ch07, modern.md
  • function literal / closure -> ch15
  • getter -> ch05
  • gofmt -> ch03
  • goroutine -> ch15
  • Handler / HandlerFunc / ServeMux patterns -> ch12, ch17, modern.md
  • loopvar (1.22 per-iteration) -> ch07, ch15, modern.md
  • if (init, omit else) -> ch07
  • init function -> ch10
  • interface -> ch12
  • make vs new -> ch09
  • map -> ch09
  • method (pointer/value receiver) -> ch11
  • MixedCaps -> ch05
  • multiple return values -> ch08
  • named results / naked return -> ch08
  • panic / recover -> ch16
  • package names -> ch05
  • rune -> ch07, ch09
  • select -> ch15
  • semicolons -> ch06
  • slice / slices.Contains -> ch09, modern.md
  • Stringer -> ch09
  • switch (on true / type switch) -> ch07, ch12
  • type assertion -> ch12, ch16
  • zero value -> ch09, ch10

Supporting Files

  • references/modern.md - 1.18–1.22 emit rules (any, errors.Is, slices, range n, loopvar, ServeMux)
  • glossary.md - all key terms with definitions
  • patterns.md - all techniques and idioms, by situation
  • cheatsheet.md - decision rules, quick tables, and tells

Scope & Limits

Chapters cover Effective Go - how to think, name, and structure Go as of the 2009 document. references/modern.md covers the small 1.18–1.22 set that agents otherwise generate from outdated training data. This skill still does not cover generics-as-language (constraints, type sets), module authoring, slog, iterators, or anything 1.23+. Honor the module go line: do not emit APIs newer than it. For hands-on work, use this skill alongside the project's own conventions.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.