All skills
cxuu avatar

/go-interfaces

@91f0c2e
by Charles Xucxuu/golang-skills165 stars
19

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).

Use this Skill: https://skilld.dev/gh/cxuu/golang-skills/go-interfaces

This session only. Nothing lands on disk.

referencesEMBEDDING.md

≈910 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Embedding Patterns in Go

Sources: Effective Go, Uber Style Guide

Go uses embedding for composition instead of inheritance. Embedding promotes the inner type's methods to the outer type, satisfying interfaces automatically.

Interface Embedding

Combine interfaces by embedding them:

type ReadWriter interface {
    Reader
    Writer
}

A ReadWriter can do what a Reader does and what a Writer does. Only interfaces can be embedded within interfaces.

Struct Embedding

Embedding promotes methods from the inner type to the outer type without explicit forwarding.

type ReadWriter struct {
    *Reader  // *bufio.Reader
    *Writer  // *bufio.Writer
}

With embedding, bufio.ReadWriter satisfies io.Reader, io.Writer, and io.ReadWriter automatically.

Mix embedded and named fields:

type Job struct {
    Command string
    *log.Logger
}

job.Println("starting now...")
job.Logger.SetPrefix("Job: ")

Method Overriding

Define a method on the outer type to override the promoted method:

func (job *Job) Printf(format string, args ...any) {
    job.Logger.Printf("%q: %s", job.Command, fmt.Sprintf(format, args...))
}

The outer method takes precedence — calls to job.Printf(...) invoke the outer method, while the embedded method is still accessible via job.Logger.Printf(...).

Embedding vs Subclassing

When an embedded method is invoked, the receiver is the inner type, not the outer one. The embedded type has no knowledge that it is embedded — there is no equivalent to this or super referencing the containing type.

type Base struct{}
func (b *Base) Name() string { return "Base" }

type Derived struct{ Base }

d := Derived{}
d.Name() // returns "Base", not "Derived"

Name Conflict Resolution

  1. Outer hides inner — Fields or methods on the outer type shadow those promoted from an embedded type at the same name
  2. Same-level conflicts are errors — If two embedded types at the same depth promote the same name, it is a compile error (unless the name is never accessed)
type A struct{}
func (A) Hello() string { return "A" }

type B struct{}
func (B) Hello() string { return "B" }

type C struct {
    A
    B
}

// c.Hello()  // compile error: ambiguous selector
c.A.Hello()   // OK: explicit disambiguation

Don't Embed in Public Structs

Embedding exposes the inner type's full method set as part of your public API. This creates a maintenance burden: changes to the embedded type's methods break your API's compatibility guarantees.

Bad

type SMap struct {
    sync.Mutex  // Lock and Unlock are now part of SMap's API
    data map[string]string
}

Good

type SMap struct {
    mu   sync.Mutex  // unexported field — implementation detail
    data map[string]string
}

func (m *SMap) Get(k string) string {
    m.mu.Lock()
    defer m.mu.Unlock()
    return m.data[k]
}

Exception: Embedding is acceptable in test types and internal structs where API stability is not a concern.

The HandlerFunc Adapter Pattern

Methods can be defined on any named type, not just structs. The http.HandlerFunc pattern converts an ordinary function into an interface implementation:

type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, req *Request) {
    f(w, req)
}

Any function with the right signature becomes an HTTP handler:

http.Handle("/args", http.HandlerFunc(ArgServer))

This adapter pattern is useful whenever you need a single-method interface satisfied by a standalone function.

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk MEDIUM
  • Gen Agent Trust Hub17d

    The skill includes a Go-based static analysis tool that is compiled and executed at runtime. It also processes external Go source files, which creates a potential surface for indirect prompt injection attacks.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    2 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 91f0c2e. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 3 months ago
What it can do
Runs commands
All 1 allowed tools
Bash(bash:*)

README badge

README badge for cxuu/golang-skills/go-interfaces