Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Language-specific super-code guidelines for go.
.claude/skills/lingxling-go/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-08 | ✓→✓ | = Same ✓ | 32% | 0% |
| case-21 | ✓→✓ | = Same ✓ | 44% | 0% |
| case-22 | ✓→✓ | = Same ✓ | 47% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 73% | 0% |
go// ❌ Ignoring errors result, _ := os.Open(path) // ✅ — always handle; only use _ when error is provably irrelevant result, err := os.Open(path) if err != nil { return fmt.Errorf("open %s: %w", path, err) }
go// ❌ Redundant error variable err := doA() if err != nil { return err } err = doB() if err != nil { return err } // ✅ — each :=/: is fine; this is idiomatic Go. Don't try to "fix" it. // What you CAN simplify: collapsing to one-liners where the if body is a single return if err := doA(); err != nil { return err } if err := doB(); err != nil { return err }
go// ❌ Custom error type with no added value type MyError struct{ msg string } func (e MyError) Error() string { return e.msg } // ✅ — use errors.New or fmt.Errorf unless callers need to inspect type var ErrNotFound = errors.New("not found") return fmt.Errorf("lookup %q: %w", key, ErrNotFound)
Wrap errors with %w (not %v) so callers can use errors.Is / errors.As.
go// ❌ Growing a slice without pre-allocation when size is known var result []string for _, item := range items { result = append(result, item.Name) } // ✅ result := make([]string, 0, len(items)) for _, item := range items { result = append(result, item.Name) }
go// ❌ Manual existence check before map write if _, ok := m[key]; !ok { m[key] = []string{} } m[key] = append(m[key], value) // ✅ — append to nil slice is valid Go m[key] = append(m[key], value)
go// ❌ Copying a map by assignment (copies reference) copy := original // ✅ copy := make(map[K]V, len(original)) for k, v := range original { copy[k] = v }
go// ❌ Fire-and-forget goroutine with no lifecycle go doWork() // ✅ — use errgroup or WaitGroup to track completion var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() doWork() }() wg.Wait()
go// ❌ Unbuffered channel causing unnecessary goroutine block ch := make(chan Result) go func() { ch <- compute() }() result := <-ch // ✅ — for single-result, buffered channel avoids goroutine leak if receiver exits early ch := make(chan Result, 1) go func() { ch <- compute() }() result := <-ch
go// ❌ select with a busy-wait default for { select { case v := <-ch: process(v) default: // spin } } // ✅ — blocking select unless you genuinely need non-blocking for v := range ch { process(v) }
Use golang.org/x/sync/errgroup for fan-out with error collection.
go// ❌ Large interface type Storage interface { Get(key string) ([]byte, error) Set(key string, val []byte) error Delete(key string) error List(prefix string) ([]string, error) // ... 10 more methods } // ✅ — small, composable interfaces type Getter interface { Get(key string) ([]byte, error) } type Setter interface { Set(key string, val []byte) error } type Storage interface { Getter; Setter }
go// ❌ Returning concrete struct from constructor (ties callers to implementation) func NewStore() *RedisStore { ... } // ✅ — return interface when you have or anticipate multiple implementations func NewStore() Storage { return &RedisStore{...} }
go// ❌ Pointer receiver for tiny value types func (p *Point) X() float64 { return p.x } // ✅ — value receiver for small immutable types func (p Point) X() float64 { return p.x }
Rule: pointer receiver when method mutates state OR struct is large (>3 fields of non-trivial size). Value receiver otherwise.
go// ❌ Named return values used just to avoid a variable declaration func divide(a, b float64) (result float64, err error) { result = a / b return } // ✅ — named returns are worth it only for deferred mutation or documentation func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil }
go// ❌ Closure capturing loop variable (classic Go bug, fixed in Go 1.22+) // Pre-1.22: each goroutine captures the same i for i := 0; i < n; i++ { go func() { use(i) }() } // ✅ (Go <1.22 — pass as parameter) for i := 0; i < n; i++ { go func(i int) { use(i) }(i) } // Go 1.22+: loop variable scoped per iteration, so the original is safe
| Anti-pattern | Preferred | |---|---| | if err != nil { return err } repeated 5+ times | acceptable — it's idiomatic Go | | panic for expected errors | return err | | init() with side effects | explicit initialization in main or constructors | | interface{} / any without generics | use generics (Go 1.18+) or typed interfaces | | Mutex field not adjacent to the data it protects | put mu directly above the field it guards | | Channel of channels | usually a sign of over-engineering; redesign | | time.Sleep in tests | use testing hooks or channels for synchronization | | Exported types with unexported fields (when fields are the whole point) | record-style structs with all-exported fields | | log.Fatal outside main | return errors up the stack |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | pass→pass | 15,219 | 12,142 | -20% | 1 | 1 | 0% | 2,672 | 3,517 | +32% | 0 | 0 | — |
case-21 | pass→pass | 22,342 | 16,428 | -26% | 1 | 1 | 0% | 3,226 | 4,636 | +44% | 0 | 0 | — |
case-22 | pass→pass | 14,563 | 24,782 | +70% | 1 | 1 | 0% | 2,543 | 3,727 | +47% | 0 | 0 | — |
case-01 | fail→fail | 25,998 | 23,238 | -11% | 1 | 1 | 0% | 3,749 | 5,275 | +41% | 0 | 0 | — |
case-02 | pass→pass | 8,158 | 7,355 | -10% | 1 | 1 | 0% | 1,586 | 2,746 | +73% | 0 | 0 | — |
case-03 | fail→pass | 14,773 | 7,304 | -51% | 1 | 1 | 0% | 2,143 | 2,956 | +38% | 0 | 0 | — |
case-04 | pass→pass | 8,736 | 5,589 | -36% | 1 | 1 | 0% | 1,595 | 2,517 | +58% | 0 | 0 | — |
case-05 | pass→pass | 8,436 | 5,336 | -37% | 1 | 1 | 0% | 1,607 | 2,781 | +73% | 0 | 0 | — |
case-06 | pass→pass | 11,482 | 8,367 | -27% | 1 | 1 | 0% | 1,955 | 2,914 | +49% | 0 | 0 | — |
case-07 | pass→pass | 11,432 | 11,597 | +1% | 1 | 1 | 0% | 2,008 | 3,405 | +70% | 0 | 0 | — |
case-09 | pass→pass | 9,966 | 5,809 | -42% | 1 | 1 | 0% | 1,781 | 2,594 | +46% | 0 | 0 | — |
case-10 | pass→pass | 11,635 | 4,901 | -58% | 1 | 1 | 0% | 1,568 | 2,555 | +63% | 0 | 0 | — |
case-11 | pass→pass | 15,848 | 11,647 | -27% | 1 | 1 | 0% | 2,979 | 3,933 | +32% | 0 | 0 | — |
case-12 | pass→pass | 15,381 | 8,023 | -48% | 1 | 1 | 0% | 2,331 | 2,844 | +22% | 0 | 0 | — |
case-13 | pass→pass | 7,356 | 5,423 | -26% | 1 | 1 | 0% | 1,246 | 2,453 | +97% | 0 | 0 | — |
case-14 | pass→pass | 11,499 | 10,492 | -9% | 1 | 1 | 0% | 2,122 | 3,226 | +52% | 0 | 0 | — |
case-15 | pass→pass | 18,781 | 11,651 | -38% | 1 | 1 | 0% | 2,600 | 4,003 | +54% | 0 | 0 | — |
case-16 | pass→pass | 14,932 | 17,347 | +16% | 1 | 1 | 0% | 2,763 | 4,313 | +56% | 0 | 0 | — |
case-17 | pass→pass | 12,463 | 12,450 | -0% | 1 | 1 | 0% | 2,293 | 4,139 | +81% | 0 | 0 | — |
case-18 | pass→pass | 17,652 | 11,397 | -35% | 1 | 1 | 0% | 2,520 | 3,240 | +29% | 0 | 0 | — |
case-19 | pass→pass | 19,403 | 15,125 | -22% | 1 | 1 | 0% | 3,016 | 4,655 | +54% | 0 | 0 | — |
case-20 | pass→pass | 11,853 | 8,652 | -27% | 1 | 1 | 0% | 1,984 | 2,985 | +50% | 0 | 0 | — |
case-23 | pass→pass | 14,202 | 11,779 | -17% | 1 | 1 | 0% | 2,175 | 3,480 | +60% | 0 | 0 | — |
case-24 | pass→pass | 11,757 | 7,156 | -39% | 1 | 1 | 0% | 1,695 | 2,991 | +76% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.