К основному содержанию
скилл CX Codex

go-generics — скилл для Claude Code: когда нужны дженерики в Go

Скилл подсказывает, когда в Go стоит брать дженерики, а когда хватит конкретных типов или интерфейса. Полезен, если пишете утилиту под несколько типов.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add cxuu/golang-skills --skill go-generics -a claude-code
Открыть на GitHub

Что делает go-generics

Скилл разбирает решения вокруг параметров типов в Go: писать ли дженерик вообще, как назвать параметр, как собрать ограничение. Отправная точка простая — сначала конкретный тип, обобщать только когда появился второй. Если несколько типов делят одну логику и общего интерфейса нет, тогда дженерики; если интерфейс уже описывает поведение, дженерик лишний.

Внутри лежит разбор частых ошибок: обёртка над стандартными типами ради одного места вызова, дженерик только чтобы удовлетворить интерфейс, слишком узкое ограничение вместо comparable. Ограничения собираются через ~ для базового типа и | для объединения, а для стандартных случаев скилл советует брать cmp.Ordered из cmp вместо своей записи. Псевдонимы типов (type Old = new.Name) оставлены под миграцию пакетов и постепенный рефакторинг API.

Дженерики требуют Go 1.18+, а cmp.Ordered — Go 1.21+. Проверьте версию тулчейна в go.mod, иначе код просто не соберётся. Проектирование интерфейсов без дженериков сюда не входит — для этого есть отдельный скилл go-interfaces.

Какие задачи решает

  • решить, нужен ли дженерик в конкретной функции
  • подобрать ограничение для параметра типа
  • выбрать между интерфейсом и дженериком
  • переписать утилиту, которая дублируется под каждый тип
  • отличить псевдоним типа от определения типа

Примеры запросов агенту

  • Напиши функцию фильтрации слайса так, чтобы она работала с несколькими типами — стоит ли тут брать дженерики?
  • Проверь моё ограничение типа: не слишком ли оно узкое?
  • Замени самописное ограничение на стандартное из cmp, если это уместно

Как установить go-generics

1Через Skills CLI (Vercel)

npx skills add cxuu/golang-skills --skill go-generics -a claude-code

2Вручную: положить файлы

~/.claude/skills/go-generics/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/go-generics/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора19

go-naming Скилл следит за именами в Go: пакеты, типы, функции, константы, получатели. Пригодится, когда агент создаёт новые типы или экспортируемое API. CX Codex +1 1 200установок go-context Задаёт правила работы с context.Context в Go: от сигнатур функций и таймаутов до разделения данных запроса и параметров. CX Codex +1 1 200установок go-style-core Скилл задаёт базовые правила оформления Go-кода: отступы, вложенность, naked returns, точки с запятой. Пригодится, когда агент пишет или правит код на Go. CX Codex +1 1 200установок go-performance Скилл для оптимизации Go: подсказывает, где заменить fmt на strconv, как задать ёмкость слайса и когда хватит strings.Builder. CX Codex +1 1 200установок go-interfaces Направляет агента при проектировании интерфейсов в Go, композиции типов и проверке контрактов. Помогает избежать преждевременных абстракций в публичном API. CX Codex +1 1 200установок go-declarations Скилл для ИИ-агента, который подсказывает, как объявлять переменные, константы, структуры и мапы в Go. Пригодится, когда пишете новый struct или блок const. CX Codex +1 1 000установок go-functions Скилл задаёт правила порядка функций в файле Go, оформления сигнатур и форматирования строк. Пригодится при написании или рефакторинге методов. CX Codex +1 1 000установок go-logging Скилл для ИИ-агента, который подсказывает, как писать логи в Go: уровни, структурные поля, контекст запроса. Пригодится, когда проект на Go обрастает логами и надо навести порядок. CX Codex +1 1 000установок

Похожие

128-java-generics Juan Antonio Breña Moral Скилл разбирает Java-код по дженерикам: убирает raw types, чинит unchecked-касты, подсказывает PECS для wildcard. Пригодится, когда API на дженериках расползается. CX Codex +1 370установок golang-data-structures samber Помогает выбирать структуры данных Go и разбираться в устройстве слайсов, map и контейнеров. Пригодится при проектировании обобщённых коллекций и работе с указателями. CX Codex +1 40 300установок golang-samber-lo samber Скилл добавляет в Claude Code знание о samber/lo — библиотеке с 500+ типобезопасными функциями для работы со срезами, картами и каналами в Go. Помогает писать функциональный код без ручных циклов и боilerplate. CX Codex +1 38 500установок typescript-pro https://github.com/Jeffallan Настраивает строгую типизацию TypeScript, генерирует брендированные типы и связывает tRPC. Пригодится при проектировании надёжных API и сложных generic-структур. CX Codex +1 14 200установок python-type-safety Seth Hobson Помогает добавлять типы в Python-код, писать дженерики и протоколы, а также настраивать строгую проверку через mypy или pyright. CX Codex 12 643установок typescript-magician mcollina Устраняет ошибки TypeScript, заменяет any на строгие типы и строит типобезопасные дженерики. Помогает навести порядок в типах кодовой базы. CX Codex +1 2 800установок

Рядом в теме «Языки программирования»

Все скиллы по теме «Языки программирования» →

Вопросы о go-generics

Как установить go-generics в Claude?

Через skills CLI: npx skills add cxuu/golang-skills --skill go-generics -a claude-code. После этого файл скилла лежит в ~/.claude/skills/go-generics/SKILL.md.

Что делает go-generics?

Помогает решить, когда в Go уместны параметры типов, как выбирать ограничения и чем псевдоним типа отличается от определения. Срабатывает и тогда, когда вы пишете утилиту под несколько типов без слова «generics».

С какой версией Go это работает?

Дженерики появились в Go 1.18, а cmp.Ordered — в Go 1.21. Если в go.mod версия ниже, часть примеров не соберётся.

Исходный текст

SKILL.md · Apache-2.0
---
name: go-generics
description: Use when deciding whether to use Go generics, writing generic functions or types, choosing constraints, or picking between type aliases and type definitions. Also use when a user is writing a utility function that could work with multiple types, even if they don't mention generics explicitly. Does not cover interface design without generics (see go-interfaces).
---

# Go Generics and Type Parameters

> Compatibility: Generics require Go 1.18+.

## Resource Routing

- `references/CONSTRAINTS.md` - Read when composing constraints, using type sets, or choosing between generics and interfaces.

## When to Use Generics

Start with concrete types. Generalize only when a second type appears.

### Prefer Generics When

- Multiple types share identical logic (sorting, filtering, map/reduce)
- You would otherwise rely on `any` and excessive type switching
- You are building a reusable data structure (concurrent-safe set, ordered map)

### Avoid Generics When

- Only one type is being instantiated in practice
- Interfaces already model the shared behavior cleanly
- The generic code is harder to read than the type-specific alternative

> "Write code, don't design types." — Robert Griesemer and Ian Lance Taylor

### Decision Flow

```
Do multiple types share identical logic?
├─ No  → Use concrete types
├─ Yes → Do they share a useful interface?
│        ├─ Yes → Use an interface
│        └─ No  → Use generics
```

**Bad:**

```go
// Premature generics: only ever called with int
func Sum[T constraints.Integer | constraints.Float](vals []T) T {
    var total T
    for _, v := range vals {
        total += v
    }
    return total
}
```

**Good:**

```go
func SumInts(vals []int) int {
    var total int
    for _, v := range vals {
        total += v
    }
    return total
}
```

---

## Type Parameter Naming

| Name | Typical Use |
|------|-------------|
| `T` | General type parameter |
| `K` | Map key type |
| `V` | Map value type |
| `E` | Element/item type |

For complex constraints, a short descriptive name is acceptable:

```go
func Marshal[Opts encoding.MarshalOptions](v any, opts Opts) ([]byte, error)
```

---

## Type Aliases vs Type Definitions

Type aliases (`type Old = new.Name`) are rare — use only for package migration
or gradual API refactoring.

---

## Constraint Composition

Combine constraints with `~` (underlying type) and `|` (union):

```go
type Numeric interface {
    ~int | ~int8 | ~int16 | ~int32 | ~int64 |
    ~float32 | ~float64
}

func Sum[T Numeric](vals []T) T {
    var total T
    for _, v := range vals {
        total += v
    }
    return total
}
```

Use the `constraints` package or `cmp` package (Go 1.21+) for standard constraints
like `cmp.Ordered` instead of writing your own.

---

## Common Pitfalls

### Don't Wrap Standard Library Types

```go
// Bad: generic wrapper adds complexity without value
type Set[T comparable] struct {
    m map[T]struct{}
}

// Better: use map[T]struct{} directly when the usage is simple
seen := map[string]struct{}{}
```

Generics justify their complexity when they eliminate duplication across
**multiple call sites**. A single-use generic is just indirection.

### Don't Use Generics for Interface Satisfaction

```go
// Bad: T is only used to satisfy an interface — just use the interface
func Process[T io.Reader](r T) error { ... }

// Good: accept the interface directly
func Process(r io.Reader) error { ... }
```

### Avoid Over-Constraining

```go
// Bad: constraint is more restrictive than needed
func Contains[T interface{ ~int | ~string }](slice []T, target T) bool { ... }

// Good: comparable is sufficient
func Contains[T comparable](slice []T, target T) bool { ... }
```

---

## Quick Reference

| Topic | Guidance |
|-------|----------|
| When to use generics | Only when multiple types share identical logic and interfaces don't suffice |
| Starting point | Write concrete code first; generalize later |
| Naming | Single uppercase letter (`T`, `K`, `V`, `E`) |
| Type aliases | Same type, alternate name; use only for migration |
| Constraint composition | Use `~` for underlying types, `|` for unions; prefer `cmp.Ordered` over custom |
| Common pitfall | Don't genericize single-use code or when interfaces suffice |

---

## Related Skills

- **Interfaces vs generics**: See [go-interfaces](../go-interfaces/SKILL.md) when deciding whether an interface already models the shared behavior without generics
- **Type declarations**: See [go-declarations](../go-declarations/SKILL.md) when defining new types, type aliases, or choosing between type definitions and aliases
- **Documenting generic APIs**: See [go-documentation](../go-documentation/SKILL.md) when writing doc comments and runnable examples for generic functions
- **Naming type parameters**: See [go-naming](../go-naming/SKILL.md) when choosing names for type parameters or constraint interfaces

© cxuu · Apache-2.0 · cxuu/golang-skills

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой