> go-functions
Use when organizing functions within a Go file, formatting function signatures, designing return values, or following Printf-style naming conventions. Also use when a user is adding or refactoring any Go function, even if they don't mention function design or signature formatting. Does not cover functional options constructors (see go-functional-options).
curl "https://skillshub.wtf/cxuu/golang-skills/go-functions?format=md"Go Function Design
When this skill does NOT apply: For functional options constructors (
WithTimeout,WithLogger), see go-functional-options. For error return conventions, see go-error-handling. For naming functions and methods, see go-naming.
Function Grouping and Ordering
Organize functions in a file by these rules:
- Functions sorted in rough call order
- Functions grouped by receiver
- Exported functions appear first, after
struct/const/vardefinitions NewXxx/newXxxconstructors appear right after the type definition- Plain utility functions appear toward the end of the file
type something struct{ ... }
func newSomething() *something { return &something{} }
func (s *something) Cost() int { return calcCost(s.weights) }
func (s *something) Stop() { ... }
func calcCost(n []int) int { ... }
Function Signatures
Read references/SIGNATURES.md when formatting multi-line signatures, wrapping return values, shortening call sites, or replacing naked bool parameters with custom types.
Keep the signature on a single line when possible. When it must wrap, put all arguments on their own lines with a trailing comma:
func (r *SomeType) SomeLongFunctionName(
foo1, foo2, foo3 string,
foo4, foo5, foo6 int,
) {
foo7 := bar(foo1)
}
Add /* name */ comments for ambiguous arguments, or better yet, replace naked
bool parameters with custom types.
Pointers to Interfaces
You almost never need a pointer to an interface. Pass interfaces as values — the underlying data can still be a pointer.
// Bad: pointer to interface
func process(r *io.Reader) { ... }
// Good: pass the interface value
func process(r io.Reader) { ... }
Printf and Stringer
Read references/PRINTF-STRINGER.md when using Printf verbs beyond %v/%s/%d, implementing fmt.Stringer or fmt.GoStringer, writing custom Format() methods, or debugging infinite recursion in String() methods.
Printf-style Function Names
Functions that accept a format string should end in f for go vet support.
Declare format strings as const when used outside Printf calls.
Prefer %q over %s with manual quoting when formatting strings for logging
or error messages — it safely escapes special characters and wraps in quotes:
return fmt.Errorf("unknown key %q", key) // produces: unknown key "foo\nbar"
See go-functional-options when designing a constructor with 3+ optional parameters.
Quick Reference
| Topic | Rule |
|---|---|
| File ordering | Type -> constructor -> exported -> unexported -> utils |
| Signature wrapping | All args on own lines with trailing comma |
| Naked parameters | Add /* name */ comments or use custom types |
| Pointers to interfaces | Almost never needed; pass interfaces by value |
| Printf function names | End with f for go vet support |
Related Skills
- Error returns: See go-error-handling when designing error return patterns or wrapping errors in multi-return functions
- Naming conventions: See go-naming when naming functions, methods, or choosing getter/setter patterns
- Functional options: See go-functional-options when designing a constructor with 3+ optional parameters
- Formatting principles: See go-style-core when deciding line length, naked returns, or signature formatting
> related_skills --same-repo
> go-testing
Use when writing, reviewing, or improving Go test code — including table-driven tests, subtests, parallel tests, test helpers, test doubles, and assertions with cmp.Diff. Also use when a user asks to write a test for a Go function, even if they don't mention specific patterns like table-driven tests or subtests. Does not cover benchmark performance testing (see go-performance).
> go-style-core
Use when working with Go formatting, line length, nesting, naked returns, semicolons, or core style principles. Also use when a style question isn't covered by a more specific skill, even if the user doesn't reference a specific style rule. Does not cover domain-specific patterns like error handling, naming, or testing (see specialized skills). Acts as fallback when no more specific style skill applies.
> go-performance
Use when optimizing Go code, investigating slow performance, or writing performance-critical sections. Also use when a user mentions slow Go code, string concatenation in loops, or asks about benchmarking, even if the user doesn't explicitly mention performance patterns. Does not cover concurrent performance patterns (see go-concurrency).
> go-packages
Use when creating Go packages, organizing imports, managing dependencies, or deciding how to structure Go code into packages. Also use when starting a new Go project or splitting a growing codebase into packages, even if the user doesn't explicitly ask about package organization. Does not cover naming individual identifiers (see go-naming).