go-code-review
Use when reviewing Go code or checking code against community style standards. Also use proactively before submitting a Go PR or…
Use when designing a Go constructor or factory function with optional configuration — especially with 3+ optional parameters or extensible APIs. Also use when building a New* function that takes many settings, even if they don't mention "functional options" by name. Does not
$ npx -y skills add cxuu/golang-skills --skill go-functional-options --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/go-functional-optionsContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when designing a Go constructor or factory function with optional configuration — especially with 3+ optional parameters or extensible APIs. Also use when building a New* function that takes many settings, even if they don't mention "functional options" by name. Does not
name: go-functional-options description: Use when designing a Go constructor or factory function with optional configuration — especially with 3+ optional parameters or extensible APIs. Also use when building a New* function that takes many settings, even if they don't mention "functional options" by name. Does not cover general function design (see go-functions).
Functional options is a pattern where you declare an opaque `Option` type that records information in an internal struct. The constructor accepts a variadic number of these options and applies them to configure the result.
Use functional options when:
1. **Unexported `options` struct** - holds all configuration 2. **Exported `Option` interface** - with unexported `apply` method 3. **Option types** - implement the interface 4. **`With*` constructors** - create options
type Option interface {
apply(*options)
}The unexported `apply` method ensures only options from this package can be used.
| Aspect | Functional Options | Config Struct | |--------|-------------------|---------------| | **Extensibility** | Add new `With*` functions | Add new fields (may break) | | **Defaults** | Built into constructor | Zero values or separate defaults | | **Caller experience** | Only specify what differs | Must construct entire struct | | **Testability** | Options are comparable | Struct comparison | | **Complexity** | More boilerplate | Simpler setup |
**Prefer Config Struct when**: Fewer than 3 options, options rarely change, all options usually specified together, or internal APIs only.
The interface approach is preferred over closure-only options because:
1. **Testability** - Options can be compared in tests and mocks 2. **Debuggability** - Options can implement `fmt.Stringer` 3. **Flexibility** - Options can implement additional interfaces 4. **Visibility** - Option types are visible in documentation
// 1. Unexported options struct with defaults
type options struct {
field1 Type1
field2 Type2
}
// 2. Exported Option interface, unexported method
type Option interface {
apply(*options)
}
// 3. Option type + apply + With* constructor
type field1Option Type1
func (o field1Option) apply(opts *options) { opts.field1 = Type1(o) }
func WithField1(v Type1) Option { return field1Option(v) }
// 4. Constructor applies options over defaults
func New(required string, opts ...Option) (*Thing, error) {
o := options{field1: defaultField1, field2: defaultField2}
for _, opt := range opts {
opt.apply(&o)
}
// ...
}AI Agent Skills for writing idiomatic, production-quality Go code. 20 modular skills teach AI coding assistants Go best practices derived from: Google Go Style Guide Effective Go Uber Go Style Guide Go Wiki CodeReviewComments Skills are tuned following
Use when reviewing Go code or checking code against community style standards. Also use proactively before submitting a Go PR or…
Use when writing concurrent Go code — goroutines, channels, mutexes, or thread-safety guarantees. Also use when parallelizing…
Use when working with context.Context in Go — placement in signatures, propagating cancellation and deadlines, and storing values…
Use when writing conditionals, loops, or switch statements in Go — including if with initialization, early returns, for loop…
Use when working with Go slices, maps, or arrays — choosing between new and make, using append, declaring empty slices (nil vs…
Use when declaring or initializing Go variables, constants, structs, or maps — including var vs :=, reducing scope with if-init,…