go-interfaces — скилл для Claude Code: что делает и как установить
Направляет агента при проектировании интерфейсов в Go, композиции типов и проверке контрактов. Помогает избежать преждевременных абстракций в публичном API.
npx skills add cxuu/golang-skills --skill go-interfaces -a claude-codeЧто делает go-interfaces
Скилл задаёт правила идиоматичного Go: интерфейс объявляется на стороне потребителя, а конструкторы возвращают конкретные структуры. Исключение сделано только для сокрытия реализации. Если тип существует исключительно ради интерфейса, конструктор возвращает интерфейс. Внутри описаны безопасное приведение типов через comma-ok, работа с type switch и выбор между указательными и структурными ресиверами.
Для защиты публичного API скилл запрещает встраивать внутренние типы в экспортируемые структуры, чтобы не раздувать набор методов. Проверять реализацию контрактов он предписывает на этапе сборки через выражение var _ I = (*T)(nil). В репозиторий входят скрипт scripts/check-interface-compliance.sh и вспомогательный код scripts/check-interface-compliance.go, находящие типы без таких проверок через Bash.
Полиморфизм на дженериках скилл намеренно не разбирает, отсылая к руководству по дженерикам. Запуск проверочного скрипта сразу вскроет пропущенные утверждения типов в кодовой базе.
Какие задачи решает
- спроектировать границы пакетов в Go без преждевременного объявления интерфейсов
- настроить проверку реализации интерфейса во время компиляции через
var _ I = (*T)(nil) - защитить публичный API от случайного раскрытия методов при встраивании структур
- реализовать безопасное приведение типов через конструкцию
comma-ok
Примеры запросов агенту
- Спроектируй consumer-интерфейс для нового сервиса отправки уведомлений на Go
- Проверь типы ресиверов и контракты в этом пакете через check-interface-compliance.sh
- Перепиши type switch с безопасным приведением типов для обработки событий
Как установить go-interfaces
1Через Skills CLI (Vercel)
npx skills add cxuu/golang-skills --skill go-interfaces -a claude-code2Вручную: положить файлы
~/.claude/skills/go-interfaces/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/go-interfaces/
1Через Skills CLI (Vercel)
npx skills add cxuu/golang-skills --skill go-interfaces -a codex2Вручную: положить файлы
.agents/skills/go-interfaces/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add cxuu/golang-skills --skill go-interfaces -a cursor2Вручную: положить файлы
.cursor/skills/go-interfaces/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install cxuu/golang-skills go-interfaces2Вручную: положить файлы
.github/skills/go-interfaces/SKILL.md1Через Skills CLI (Vercel)
npx skills add cxuu/golang-skills --skill go-interfaces -a gemini-cli2Командой платформы
gemini skills install https://github.com/cxuu/golang-skills --path skills/go-interfacesВручную: положить файлы
.devin/skills/go-interfaces/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add cxuu/golang-skills --skill go-interfaces -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора19
Похожие
Рядом в теме «Языки программирования»
Все скиллы по теме «Языки программирования» →Вопросы о go-interfaces
Как установить go-interfaces в Claude Code?
Выполните команду npx skills add cxuu/golang-skills --skill go-interfaces -a claude-code. Агент добавит скилл в рабочее окружение.
Что делает скилл go-interfaces?
Он помогает агенту проектировать Go-интерфейсы по правилу «принимай интерфейсы, возвращай структуры», избегать утечек методов через встраивание и безопасно приводить типы.
Подходит ли этот скилл для настройки дженериков в Go?
Нет, полиморфизм на базе дженериков сюда не входит. Для параметризованных типов автор скилла предусмотрел отдельное руководство go-generics.
Исходный текст
SKILL.md · Apache-2.0
---
name: go-interfaces
description: Use when defining or implementing Go interfaces, designing abstractions, creating mockable boundaries for testing, or composing types through embedding. Also use when deciding whether to accept an interface or return a concrete type, or using type assertions or type switches, even if the user doesn't explicitly mention interfaces. Does not cover generics-based polymorphism (see go-generics).
allowed-tools: Bash(bash:*)
---
# Go Interfaces and Composition
## Resource Routing
- `scripts/check-interface-compliance.sh` - Run as a heuristic to find exported interfaces that may need compile-time assertions.
- `scripts/check-interface-compliance.go` - Implementation helper invoked by `check-interface-compliance.sh`; patch this when changing method-set analysis.
- `references/EMBEDDING.md` - Read when embedding interfaces or structs in public APIs.
- `references/RECEIVER-TYPE.md` - Read when pointer/value receivers affect interface satisfaction.
---
## Accept Interfaces, Return Concrete Types
Interfaces belong in the package that **consumes** values, not the package that
**implements** them. Return concrete (usually pointer or struct) types from
constructors so new methods can be added without refactoring.
```go
// Good: consumer defines the interface it needs
package consumer
type Thinger interface { Thing() bool }
func Foo(t Thinger) string { ... }
```
```go
// Good: producer returns concrete type
package producer
type Thinger struct{ ... }
func (t Thinger) Thing() bool { ... }
func NewThinger() Thinger { return Thinger{ ... } }
```
```go
// Bad: producer defines and returns its own interface
package producer
type Thinger interface { Thing() bool }
type defaultThinger struct{ ... }
func NewThinger() Thinger { return defaultThinger{ ... } }
```
**Do not define interfaces before they are used.** Without a realistic example
of usage, it is too difficult to see whether an interface is even necessary.
---
## Generality: Hide Implementation, Expose Interface
If a type exists only to implement an interface with no exported methods beyond
that interface, return the interface from constructors to hide the implementation:
```go
func NewHash() hash.Hash32 {
return &myHash{} // unexported type
}
```
Benefits: implementation can change without affecting callers, substituting
algorithms requires only changing the constructor call.
---
## Type Assertions: Comma-Ok Idiom
Without checking, a failed assertion causes a runtime panic. Always use the
comma-ok idiom to test safely:
```go
str, ok := value.(string)
if ok {
fmt.Printf("string value is: %q\n", str)
}
```
To check if a value implements an interface:
```go
if _, ok := val.(json.Marshaler); ok {
fmt.Printf("value %v implements json.Marshaler\n", val)
}
```
---
## Type Switch
It's idiomatic to reuse the variable name (`t := t.(type)`) — the variable has
the correct type in each case branch. When a case lists multiple types
(`case int, int64:`), the variable has the interface type.
---
## Embedding
Avoid embedding types in public structs — the inner type's full method set
becomes part of your public API. Use unexported fields instead.
---
## Interface Satisfaction Checks
Use a blank identifier assignment to verify a type implements an interface at
compile time:
```go
var _ json.Marshaler = (*RawMessage)(nil)
```
This causes a compile error if `*RawMessage` doesn't implement `json.Marshaler`.
Use this pattern when:
- There are no static conversions that would verify the interface automatically
- The type must satisfy an interface for correct behavior (e.g., custom JSON
marshaling)
- Interface changes should break compilation, not silently degrade
**Don't** add these checks for every interface — only when no other static
conversion would catch the error.
> **Validation**: After defining interfaces or implementations, run `bash scripts/check-interface-compliance.sh` to verify all concrete types have compile-time `var _ I = (*T)(nil)` checks.
---
## Receiver Type
If in doubt, use a pointer receiver. Don't mix receiver types on a single
type — if any method needs a pointer, use pointers for all methods. Use value
receivers only for small, immutable types (`Point`, `time.Time`) or basic types.
---
## Quick Reference
| Concept | Pattern | Notes |
|---------|---------|-------|
| Consumer owns interface | Define interfaces where used | Not in the implementing package |
| Safe type assertion | `v, ok := x.(Type)` | Returns zero value + false |
| Type switch | `switch v := x.(type)` | Variable has correct type per case |
| Interface embedding | `type RW interface { Reader; Writer }` | Union of methods |
| Struct embedding | `type S struct { *T }` | Promotes T's methods |
| Interface check | `var _ I = (*T)(nil)` | Compile-time verification |
| Generality | Return interface from constructor | Hide implementation |
---
## Related Skills
- **Interface naming**: See [go-naming](../go-naming/SKILL.md) when naming interfaces (the `-er` suffix convention) or choosing receiver names
- **Error types**: See [go-error-handling](../go-error-handling/SKILL.md) when implementing the `error` interface, custom error types, or `errors.As` matching
- **Generics vs interfaces**: See [go-generics](../go-generics/SKILL.md) when deciding whether generics are needed or an interface already suffices
- **Functional options**: See [go-functional-options](../go-functional-options/SKILL.md) when using an interface-based Option pattern for flexible constructors
- **Defensive boundaries**: See [go-defensive](../go-defensive/SKILL.md) when interface assertions are one part of a broader API-boundary hardening pass
© cxuu · Apache-2.0 · cxuu/golang-skills