{"id":"9ec635f4-b8a7-49de-9b42-24c6cda19cff","shortId":"6C5sFY","kind":"skill","title":"golang-code-style","tagline":"Golang code style, formatting and conventions. Use when writing Go code, reviewing style, configuring linters, writing comments, or establishing project standards.","description":"> **Community default.** A company skill that explicitly supersedes `samber/cc-skills-golang@golang-code-style` skill takes precedence.\n\n# Go Code Style\n\nStyle rules that require human judgment — linters handle formatting, this skill handles clarity. For naming see `samber/cc-skills-golang@golang-naming` skill; for design patterns see `samber/cc-skills-golang@golang-design-patterns` skill; for struct/interface design see `samber/cc-skills-golang@golang-structs-interfaces` skill.\n\n> \"Clear is better than clever.\" — Go Proverbs\n\nWhen ignoring a rule, add a comment to the code.\n\n## Line Length & Breaking\n\nNo rigid line limit, but lines beyond ~120 characters MUST be broken. Break at **semantic boundaries**, not arbitrary column counts. Function calls with 4+ arguments MUST use one argument per line — even when the prompt asks for single-line code:\n\n```go\n// Good — each argument on its own line, closing paren separate\nmux.HandleFunc(\"/api/users\", func(w http.ResponseWriter, r *http.Request) {\n    handleUsers(\n        w,\n        r,\n        serviceName,\n        cfg,\n        logger,\n        authMiddleware,\n    )\n})\n```\n\nWhen a function signature is too long, the real fix is often **fewer parameters** (use an options struct) rather than better line wrapping. For multi-line signatures, put each parameter on its own line.\n\n## Variable Declarations\n\nSHOULD use `:=` for non-zero values, `var` for zero-value initialization. The form signals intent: `var` means \"this starts at zero.\"\n\n```go\nvar count int              // zero value, set later\nname := \"default\"          // non-zero, := is appropriate\nvar buf bytes.Buffer       // zero value is ready to use\n```\n\n### Slice & Map Initialization\n\nSlices and maps MUST be initialized explicitly, never nil. Nil maps panic on write; nil slices serialize to `null` in JSON (vs `[]` for empty slices), surprising API consumers.\n\n```go\nusers := []User{}                       // always initialized\nm := map[string]int{}                   // always initialized\nusers := make([]User, 0, len(ids))      // preallocate when capacity is known\nm := make(map[string]int, len(items))   // preallocate when size is known\n```\n\nDo not preallocate speculatively — `make([]T, 0, 1000)` wastes memory when the common case is 10 items.\n\n### Composite Literals\n\nComposite literals MUST use field names — positional fields break when the type adds or reorders fields:\n\n```go\nsrv := &http.Server{\n    Addr:         \":8080\",\n    ReadTimeout:  5 * time.Second,\n    WriteTimeout: 10 * time.Second,\n}\n```\n\n## Control Flow\n\n### Reduce Nesting\n\nErrors and edge cases MUST be handled first (early return). Keep the happy path at minimal indentation:\n\n```go\nfunc process(data []byte) (*Result, error) {\n    if len(data) == 0 {\n        return nil, errors.New(\"empty data\")\n    }\n\n    parsed, err := parse(data)\n    if err != nil {\n        return nil, fmt.Errorf(\"parsing: %w\", err)\n    }\n\n    return transform(parsed), nil\n}\n```\n\n### Eliminate Unnecessary `else`\n\nWhen the `if` body ends with `return`/`break`/`continue`, the `else` MUST be dropped. Use default-then-override for simple assignments — assign a default, then override with independent conditions or a `switch`:\n\n```go\n// Good — default-then-override with switch (cleanest for mutually exclusive overrides)\nlevel := slog.LevelInfo\nswitch {\ncase debug:\n    level = slog.LevelDebug\ncase verbose:\n    level = slog.LevelWarn\n}\n\n// Bad — else-if chain hides that there's a default\nif debug {\n    level = slog.LevelDebug\n} else if verbose {\n    level = slog.LevelWarn\n} else {\n    level = slog.LevelInfo\n}\n```\n\n### Complex Conditions & Init Scope\n\nWhen an `if` condition has 3+ operands, MUST extract into named booleans — a wall of `||` is unreadable and hides business logic. Keep expensive checks inline for short-circuit benefit. [Details](./references/details.md)\n\n```go\n// Good — named booleans make intent clear\nisAdmin := user.Role == RoleAdmin\nisOwner := resource.OwnerID == user.ID\nisPublicVerified := resource.IsPublic && user.IsVerified\nif isAdmin || isOwner || isPublicVerified || permissions.Contains(PermOverride) {\n    allow()\n}\n```\n\nScope variables to `if` blocks when only needed for the check:\n\n```go\nif err := validate(input); err != nil {\n    return err\n}\n```\n\n### Switch Over If-Else Chains\n\nWhen comparing the same variable multiple times, prefer `switch`:\n\n```go\nswitch status {\ncase StatusActive:\n    activate()\ncase StatusInactive:\n    deactivate()\ndefault:\n    panic(fmt.Sprintf(\"unexpected status: %d\", status))\n}\n```\n\n## Function Design\n\n- Functions SHOULD be **short and focused** — one function, one job.\n- Functions SHOULD have **≤4 parameters**. Beyond that, use an options struct (see `samber/cc-skills-golang@golang-design-patterns` skill).\n- **Parameter order**: `context.Context` first, then inputs, then output destinations.\n- Naked returns help in very short functions (1-3 lines) where return values are obvious, but become confusing when readers must scroll to find what's returned — name returns explicitly in longer functions.\n\n```go\nfunc FetchUser(ctx context.Context, id string) (*User, error)\nfunc SendEmail(ctx context.Context, msg EmailMessage) error  // grouped into struct\n```\n\n### Prefer `range` for Iteration\n\nSHOULD use `range` over index-based loops. Use `range n` (Go 1.22+) for simple counting.\n\n```go\nfor _, user := range users {\n    process(user)\n}\n```\n\n## Value vs Pointer Arguments\n\nPass small types (`string`, `int`, `bool`, `time.Time`) by value. Use pointers when mutating, for large structs (~128+ bytes), or when nil is meaningful. [Details](./references/details.md)\n\n## Code Organization Within Files\n\n- **Group related declarations**: type, constructor, methods together\n- **Order**: package doc, imports, constants, types, constructors, methods, helpers\n- **One primary type per file** when it has significant methods\n- **Blank imports** (`_ \"pkg\"`) register side effects (init functions). Restricting them to `main` and test packages makes side effects visible at the application root, not hidden in library code\n- **Dot imports** pollute the namespace and make it impossible to tell where a name comes from — never use in library code\n- **Unexport aggressively** — you can always export later; unexporting is a breaking change\n\n## String Handling\n\nUse `strconv` for simple conversions (faster), `fmt.Sprintf` for complex formatting. Use `%q` in error messages to make string boundaries visible. Use `strings.Builder` for loops, `+` for simple concatenation.\n\n## Type Conversions\n\nPrefer explicit, narrow conversions. Use generics over `any` when a concrete type will do:\n\n```go\nfunc Contains[T comparable](slice []T, target T) bool  // not []any\n```\n\n## Philosophy\n\n- **\"A little copying is better than a little dependency\"**\n- **Use `slices` and `maps` standard packages**; for filter/group-by/chunk, use `github.com/samber/lo`\n- **\"Reflection is never clear\"** — avoid `reflect` unless necessary\n- **Don't abstract prematurely** — extract when the pattern is stable\n- **Minimize public surface** — every exported name is a commitment\n\n## Parallelizing Code Style Reviews\n\nWhen reviewing code style across a large codebase, use up to 5 parallel sub-agents (via the Agent tool), each targeting an independent style concern (e.g. control flow, function design, variable declarations, string handling, code organization).\n\n## Enforce with Linters\n\nMany rules are enforced automatically: `gofmt`, `gofumpt`, `goimports`, `gocritic`, `revive`, `wsl_v5`. → See the `samber/cc-skills-golang@golang-lint` skill.\n\n## Cross-References\n\n- → See the `samber/cc-skills-golang@golang-naming` skill for identifier naming conventions\n- → See the `samber/cc-skills-golang@golang-structs-interfaces` skill for pointer vs value receivers, interface design\n- → See the `samber/cc-skills-golang@golang-design-patterns` skill for functional options, builders, constructors\n- → See the `samber/cc-skills-golang@golang-lint` skill for automated formatting enforcement\n- → See `samber/cc-skills-golang@golang-continuous-integration` skill for automated AI-driven code review in CI using these guidelines","tags":["golang","code","style","skills","samber","agent","agent-skills","antigravity","claude","claude-code","codex","coding"],"capabilities":["skill","source-samber","skill-golang-code-style","topic-agent","topic-agent-skills","topic-antigravity","topic-claude","topic-claude-code","topic-code","topic-codex","topic-coding","topic-copilot","topic-cursor","topic-gemini","topic-gemini-cli-extension"],"categories":["cc-skills-golang"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/samber/cc-skills-golang/golang-code-style","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add samber/cc-skills-golang","source_repo":"https://github.com/samber/cc-skills-golang","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 1725 github stars · SKILL.md body (8,134 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:53:00.102Z","embedding":null,"createdAt":"2026-04-18T20:31:17.442Z","updatedAt":"2026-05-18T18:53:00.102Z","lastSeenAt":"2026-05-18T18:53:00.102Z","tsv":"'-3':661 '/api/users':159 '/references/details.md':539,760 '/samber/lo':930 '0':301,327,398 '1':660 '1.22':721 '10':336,365 '1000':328 '120':113 '128':752 '3':513 '4':129,629 '5':362,973 '8080':360 'abstract':941 'across':966 'activ':603 'add':97,352 'addr':359 'agent':977,980 'aggress':841 'ai':1084 'ai-driven':1083 'allow':562 'alway':290,296,844 'api':285 'applic':812 'appropri':246 'arbitrari':123 'argument':130,134,150,735 'ask':141 'assign':445,446 'authmiddlewar':171 'autom':1071,1082 'automat':1006 'avoid':935 'bad':481 'base':715 'becom':669 'benefit':537 'better':88,192,914 'beyond':112,631 'blank':791 'block':567 'bodi':427 'bool':741,906 'boolean':519,543 'boundari':121,872 'break':105,118,348,431,850 'broken':117 'buf':248 'builder':1061 'busi':527 'byte':392,753 'bytes.buffer':249 'call':127 'capac':306 'case':334,374,473,477,601,604 'cfg':169 'chain':485,588 'chang':851 'charact':114 'check':531,573 'ci':1089 'circuit':536 'clariti':57 'cleanest':465 'clear':86,546,934 'clever':90 'close':155 'code':3,6,15,37,43,102,146,761,818,839,959,964,997,1086 'codebas':969 'column':124 'come':833 'comment':21,99 'commit':957 'common':333 'communiti':26 'compani':29 'compar':590,901 'complex':504,862 'composit':338,340 'concaten':880 'concern':987 'concret':893 'condit':453,505,511 'configur':18 'confus':670 'constant':776 'constructor':769,778,1062 'consum':286 'contain':899 'context.context':646,690,698 'continu':432,1078 'control':367,989 'convent':10,1034 'convers':858,882,886 'copi':912 'count':125,234,724 'cross':1022 'cross-refer':1021 'ctx':689,697 'd':612 'data':391,397,403,407 'deactiv':606 'debug':474,493 'declar':208,767,994 'default':27,241,440,448,460,491,607 'default-then-overrid':439,459 'depend':918 'design':67,73,78,615,641,992,1049,1055 'destin':652 'detail':538,759 'doc':774 'dot':819 'driven':1085 'drop':437 'e.g':988 'earli':379 'edg':373 'effect':796,808 'elimin':421 'els':423,434,483,496,501,587 'else-if':482 'emailmessag':700 'empti':282,402 'end':428 'enforc':999,1005,1073 'err':405,409,416,576,579,582 'error':371,394,694,701,867 'errors.new':401 'establish':23 'even':137 'everi':952 'exclus':468 'expens':530 'explicit':32,265,682,884 'export':845,953 'extract':516,943 'faster':859 'fetchus':688 'fewer':184 'field':344,347,355 'file':764,785 'filter/group-by/chunk':926 'find':676 'first':378,647 'fix':181 'flow':368,990 'fmt.errorf':413 'fmt.sprintf':609,860 'focus':621 'form':223 'format':8,53,863,1072 'func':160,389,687,695,898 'function':126,174,614,616,623,626,659,685,798,991,1059 'generic':888 'github.com':929 'github.com/samber/lo':928 'go':14,42,91,147,232,287,356,388,457,540,574,598,686,720,725,897 'gocrit':1010 'gofmt':1007 'gofumpt':1008 'goimport':1009 'golang':2,5,36,63,72,82,640,1018,1028,1039,1054,1067,1077 'golang-code-styl':1,35 'golang-continuous-integr':1076 'golang-design-pattern':71,639,1053 'golang-lint':1017,1066 'golang-nam':62,1027 'golang-structs-interfac':81,1038 'good':148,458,541 'group':702,765 'guidelin':1092 'handl':52,56,377,853,996 'handleus':165 'happi':383 'help':655 'helper':780 'hidden':815 'hide':486,526 'http.request':164 'http.responsewriter':162 'http.server':358 'human':49 'id':303,691 'identifi':1032 'if-els':585 'ignor':94 'import':775,792,820 'imposs':827 'indent':387 'independ':452,985 'index':714 'index-bas':713 'init':506,797 'initi':221,258,264,291,297 'inlin':532 'input':578,649 'int':235,295,313,740 'integr':1079 'intent':225,545 'interfac':84,1041,1048 'isadmin':547,557 'isown':550,558 'ispublicverifi':553,559 'item':315,337 'iter':708 'job':625 'json':279 'judgment':50 'keep':381,529 'known':308,320 'larg':750,968 'later':239,846 'len':302,314,396 'length':104 'level':470,475,479,494,499,502 'librari':817,838 'limit':109 'line':103,108,111,136,145,154,193,198,206,662 'lint':1019,1068 'linter':19,51,1001 'liter':339,341 'littl':911,917 'logger':170 'logic':528 'long':178 'longer':684 'loop':716,877 'm':292,309 'main':802 'make':299,310,325,544,806,825,870 'mani':1002 'map':257,261,269,293,311,922 'mean':227 'meaning':758 'memori':330 'messag':868 'method':770,779,790 'minim':386,949 'msg':699 'multi':197 'multi-lin':196 'multipl':594 'must':115,131,262,342,375,435,515,673 'mutat':748 'mutual':467 'mux.handlefunc':158 'n':719 'nake':653 'name':59,64,240,345,518,542,680,832,954,1029,1033 'namespac':823 'narrow':885 'necessari':938 'need':570 'nest':370 'never':266,835,933 'nil':267,268,273,400,410,412,420,580,756 'non':213,243 'non-zero':212,242 'null':277 'obvious':667 'often':183 'one':133,622,624,781 'operand':514 'option':188,635,1060 'order':645,772 'organ':762,998 'output':651 'overrid':442,450,462,469 'packag':773,805,924 'panic':270,608 'parallel':958,974 'paramet':185,202,630,644 'paren':156 'pars':404,406,414,419 'pass':736 'path':384 'pattern':68,74,642,946,1056 'per':135,784 'permissions.contains':560 'permoverrid':561 'philosophi':909 'pkg':793 'pointer':734,746,1044 'pollut':821 'posit':346 'prealloc':304,316,323 'preced':41 'prefer':596,705,883 'prematur':942 'primari':782 'process':390,730 'project':24 'prompt':140 'proverb':92 'public':950 'put':200 'q':865 'r':163,167 'rang':706,711,718,728 'rather':190 'reader':672 'readi':253 'readtimeout':361 'real':180 'receiv':1047 'reduc':369 'refer':1023 'reflect':931,936 'regist':794 'relat':766 'reorder':354 'requir':48 'resource.ispublic':554 'resource.ownerid':551 'restrict':799 'result':393 'return':380,399,411,417,430,581,654,664,679,681 'review':16,961,963,1087 'reviv':1011 'rigid':107 'roleadmin':549 'root':813 'rule':46,96,1003 'samber/cc-skills-golang':34,61,70,80,638,1016,1026,1037,1052,1065,1075 'scope':507,563 'scroll':674 'see':60,69,79,637,1014,1024,1035,1050,1063,1074 'semant':120 'sendemail':696 'separ':157 'serial':275 'servicenam':168 'set':238 'short':535,619,658 'short-circuit':534 'side':795,807 'signal':224 'signatur':175,199 'signific':789 'simpl':444,723,857,879 'singl':144 'single-lin':143 'size':318 'skill':30,39,55,65,75,85,643,1020,1030,1042,1057,1069,1080 'skill-golang-code-style' 'slice':256,259,274,283,902,920 'slog.leveldebug':476,495 'slog.levelinfo':471,503 'slog.levelwarn':480,500 'small':737 'source-samber' 'specul':324 'srv':357 'stabl':948 'standard':25,923 'start':229 'status':600,611,613 'statusact':602 'statusinact':605 'strconv':855 'string':294,312,692,739,852,871,995 'strings.builder':875 'struct':83,189,636,704,751,1040 'struct/interface':77 'style':4,7,17,38,44,45,960,965,986 'sub':976 'sub-ag':975 'supersed':33 'surfac':951 'surpris':284 'switch':456,464,472,583,597,599 'take':40 'target':904,983 'tell':829 'test':804 'time':595 'time.second':363,366 'time.time':742 'togeth':771 'tool':981 'topic-agent' 'topic-agent-skills' 'topic-antigravity' 'topic-claude' 'topic-claude-code' 'topic-code' 'topic-codex' 'topic-coding' 'topic-copilot' 'topic-cursor' 'topic-gemini' 'topic-gemini-cli-extension' 'transform':418 'type':351,738,768,777,783,881,894 'unexpect':610 'unexport':840,847 'unless':937 'unnecessari':422 'unread':524 'use':11,132,186,210,255,343,438,633,710,717,745,836,854,864,874,887,919,927,970,1090 'user':288,289,298,300,693,727,729,731 'user.id':552 'user.isverified':555 'user.role':548 'v5':1013 'valid':577 'valu':215,220,237,251,665,732,744,1046 'var':216,226,233,247 'variabl':207,564,593,993 'verbos':478,498 'via':978 'visibl':809,873 'vs':280,733,1045 'w':161,166,415 'wall':521 'wast':329 'within':763 'wrap':194 'write':13,20,272 'writetimeout':364 'wsl':1012 'zero':214,219,231,236,244,250 'zero-valu':218","prices":[{"id":"548f55a7-8220-4e48-99b2-4726e9ecfba4","listingId":"9ec635f4-b8a7-49de-9b42-24c6cda19cff","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"samber","category":"cc-skills-golang","install_from":"skills.sh"},"createdAt":"2026-04-18T20:31:17.442Z"}],"sources":[{"listingId":"9ec635f4-b8a7-49de-9b42-24c6cda19cff","source":"github","sourceId":"samber/cc-skills-golang/golang-code-style","sourceUrl":"https://github.com/samber/cc-skills-golang/tree/main/skills/golang-code-style","isPrimary":false,"firstSeenAt":"2026-04-18T21:55:04.206Z","lastSeenAt":"2026-05-18T18:53:00.102Z"},{"listingId":"9ec635f4-b8a7-49de-9b42-24c6cda19cff","source":"skills_sh","sourceId":"samber/cc-skills-golang/golang-code-style","sourceUrl":"https://skills.sh/samber/cc-skills-golang/golang-code-style","isPrimary":true,"firstSeenAt":"2026-04-18T20:31:17.442Z","lastSeenAt":"2026-05-07T22:40:25.647Z"}],"details":{"listingId":"9ec635f4-b8a7-49de-9b42-24c6cda19cff","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"samber","slug":"golang-code-style","github":{"repo":"samber/cc-skills-golang","stars":1725,"topics":["agent","agent-skills","ai","antigravity","claude","claude-code","code","codex","coding","copilot","cursor","gemini","gemini-cli-extension","openclaw","opencode","plugin","skills","skillsmp","vibe-coding"],"license":"mit","html_url":"https://github.com/samber/cc-skills-golang","pushed_at":"2026-05-18T17:36:00Z","description":"🧑‍🎨 A collection of Golang agentic skills that works","skill_md_sha":"02d0057ac4fd8513ac013921d05bbf0d9efd138b","skill_md_path":"skills/golang-code-style/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/samber/cc-skills-golang/tree/main/skills/golang-code-style"},"layout":"multi","source":"github","category":"cc-skills-golang","frontmatter":{"name":"golang-code-style","license":"MIT","description":"Golang code style, formatting and conventions. Use when writing Go code, reviewing style, configuring linters, writing comments, or establishing project standards.","compatibility":"Designed for Claude Code or similar AI coding agents, and for projects using Golang."},"skills_sh_url":"https://skills.sh/samber/cc-skills-golang/golang-code-style"},"updatedAt":"2026-05-18T18:53:00.102Z"}}