0Pricing
Go Academy · Lesson

Anonymous Structs and Composition

Embedding and struct-based code reuse

Anonymous Structs and Composition is a free Go Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Anonymous Structs

An anonymous struct has no named type. It's defined inline and is useful for short-lived data, table-driven tests, and one-off groupings:

package main
import "fmt"

func main() {
    point := struct{ X, Y int }{X: 3, Y: 7}
    fmt.Println(point.X, point.Y)
}

Anonymous Structs in Table Tests

A common Go idiom uses a slice of anonymous structs for table-driven tests:

package main
import "fmt"

func double(n int) int { return n * 2 }

func main() {
    tests := []struct{ input, want int }{
        {1, 2}, {5, 10}, {0, 0},
    }
    for _, tt := range tests {
        got := double(tt.input)
        if got != tt.want {
            fmt.Printf("FAIL: double(%d) = %d, want %d\n", tt.input, got, tt.want)
        }
    }
    fmt.Println("all tests passed")
}

Struct Embedding

Embedding a type inside a struct promotes its fields and methods to the outer struct:

package main
import "fmt"

type Animal struct{ Name string }
func (a Animal) Speak() string { return a.Name + " speaks" }

type Dog struct {
    Animal        // embedded
    Breed string
}

func main() {
    d := Dog{Animal: Animal{"Rex"}, Breed: "Labrador"}
    fmt.Println(d.Name)    // promoted field
    fmt.Println(d.Speak()) // promoted method
}

Multiple Embedding

A struct can embed multiple types. Conflicts (same field/method name) must be resolved explicitly:

package main
import "fmt"

type Logger struct{}
func (Logger) Log(s string) { fmt.Println("[LOG]", s) }

type Metrics struct{}
func (Metrics) Count() int { return 42 }

type Service struct {
    Logger
    Metrics
    Name string
}

func main() {
    svc := Service{Name: "auth"}
    svc.Log("started")       // from Logger
    fmt.Println(svc.Count()) // from Metrics
}

Embedding vs Inheritance

Go has no class inheritance. Embedding is composition:

  • Embedding promotes fields and methods, but the outer type is not a subtype
  • You cannot pass a Dog where an Animal is expected
  • Use interfaces for polymorphism, embedding for code reuse

Overriding Promoted Methods

The outer struct can shadow an embedded method by defining its own:

package main
import "fmt"

type Base struct{}
func (Base) Hello() string { return "Base hello" }

type Child struct{ Base }
func (Child) Hello() string { return "Child hello" } // shadows Base.Hello

func main() {
    c := Child{}
    fmt.Println(c.Hello())      // Child hello
    fmt.Println(c.Base.Hello()) // Base hello (explicit)
}

Anonymous Struct for Config

Use an anonymous struct to group related config without defining a named type:

package main
import "fmt"

func main() {
    cfg := struct {
        Host string
        Port int
        TLS  bool
    }{
        Host: "api.example.com",
        Port: 443,
        TLS:  true,
    }
    fmt.Println(cfg)
}

Embedding an Interface

Embedding an interface in a struct is useful for mocking and default implementations:

package main
import "fmt"

type Reader interface{ Read() string }

type Mock struct{ Reader }  // embed interface

func main() {
    m := Mock{}
    fmt.Printf("%T\n", m.Reader) // <nil> — not set
    // Assign a real impl at test time:
    _ = m
}

Struct Composition Pitfalls

Watch out for:

  • Ambiguous selectors when two embedded types have the same field/method name
  • Nil embedded pointer causing a panic when you call methods on it
  • Forgetting that embedding is not inheritance — you can't substitute the outer type for the embedded type

Comparing Anonymous Structs

Two anonymous structs with the same field names and types are assignable to each other if their tags also match:

package main
import "fmt"

func main() {
    a := struct{ X, Y int }{1, 2}
    b := struct{ X, Y int }{1, 2}
    fmt.Println(a == b) // true
}

Quick Check

What does embedding a type in a struct achieve?

Recap: Composition

Key takeaways:

  • Anonymous structs are great for table tests and short-lived data
  • Embedding promotes fields and methods — it's composition, not inheritance
  • Outer types can shadow embedded methods
  • Resolve ambiguous selectors explicitly
  • Use interfaces for polymorphism

Practice Prompt

Create a TimestampedRecord struct that embeds a Timestamp struct{ CreatedAt, UpdatedAt string } and a Data struct{ Key, Value string }. Instantiate it and print all promoted fields.

Frequently asked questions

Is the “Anonymous Structs and Composition” lesson free?

Yes — the full text of “Anonymous Structs and Composition” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “Anonymous Structs and Composition”?

Embedding and struct-based code reuse You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Anonymous Structs and Composition” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Defining and Using Structs
  2. Methods on Structs
  3. Constructor Patterns
  4. Anonymous Structs and Composition
← Back to Go Academy