Understanding Struct Inheritance in Go
Daniel Hayes
Full-Stack Engineer · Leapcell

Key Takeaways
- Go uses struct composition instead of class-based inheritance.
- Embedded structs promote fields and methods to the outer struct.
- Interfaces enable polymorphism without requiring explicit inheritance.
In many object-oriented programming languages, inheritance allows a new class to acquire properties and behaviors from an existing class. However, Go (Golang) takes a different approach. Instead of traditional class-based inheritance, Go utilizes composition to achieve similar outcomes. This article explores how Go's struct composition works and how it can be used to build complex data structures.
Structs in Go
In Go, a struct
is a composite data type that groups together variables under a single name. These variables, known as fields, can be of different types. Here's a simple example:
package main import "fmt" type Person struct { Name string Age int } func main() { p := Person{Name: "Alice", Age: 30} fmt.Println(p) }
In this example, Person
is a struct with two fields: Name
and Age
.
Composition over Inheritance
Go promotes the use of composition over inheritance. Instead of creating a hierarchical class structure, Go allows you to build complex types by combining simple ones. This is achieved by embedding structs within other structs.
Embedding Structs
When a struct is embedded within another struct, the fields and methods of the embedded struct become accessible through the outer struct. Here's how it works:
package main import "fmt" type Address struct { City, State string } type Person struct { Name string Age int Address // Embedding Address struct } func main() { p := Person{ Name: "Bob", Age: 25, Address: Address{ City: "New York", State: "NY", }, } fmt.Println(p) fmt.Println("City:", p.City) // Accessing embedded field directly }
In this example, Person
embeds the Address
struct. This means Person
inherits the fields of Address
, allowing direct access to City
and State
through a Person
instance.
Method Promotion
Methods defined on an embedded struct are promoted to the outer struct. This allows the outer struct to access the embedded struct's methods as if they were its own.
package main import "fmt" type Address struct { City, State string } func (a Address) FullAddress() string { return a.City + ", " + a.State } type Person struct { Name string Age int Address } func main() { p := Person{ Name: "Charlie", Age: 28, Address: Address{ City: "Los Angeles", State: "CA", }, } fmt.Println(p.FullAddress()) // Calling method from embedded struct }
Here, FullAddress
is a method of Address
but can be called on Person
because of embedding.
Interfaces and Polymorphism
While Go doesn't support traditional inheritance, it provides powerful interface capabilities that enable polymorphism. Interfaces define a set of methods that a type must implement. Any type that implements these methods satisfies the interface.
package main import "fmt" type Describer interface { Describe() string } type Person struct { Name string Age int } func (p Person) Describe() string { return fmt.Sprintf("%s is %d years old.", p.Name, p.Age) } type Product struct { Name string Price float64 } func (p Product) Describe() string { return fmt.Sprintf("%s costs $%.2f.", p.Name, p.Price) } func PrintDescription(d Describer) { fmt.Println(d.Describe()) } func main() { p := Person{Name: "Dave", Age: 22} pr := Product{Name: "Laptop", Price: 999.99} PrintDescription(p) PrintDescription(pr) }
In this example, both Person
and Product
types implement the Describer
interface by defining a Describe
method. The PrintDescription
function accepts any type that satisfies the Describer
interface, demonstrating polymorphism.
Conclusion
Go's approach to struct composition and interfaces provides a flexible and powerful way to build and extend types without traditional inheritance. By embedding structs and implementing interfaces, you can create complex and reusable code structures that are easy to maintain and understand.
FAQs
No, Go relies on composition rather than class-based inheritance.
By embedding one struct inside another, fields and methods are promoted to the outer struct.
By using interfaces, where any type implementing required methods satisfies the interface.
We are Leapcell, your top choice for hosting Go projects.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ