Understanding Embedded Structs in Go: Composition and Inheritance
21 views
In Go, you can use embedded structs to create a form of inheritance or composition. This allows one struct to include another struct directly, inheriting its fields and methods. Embedded structs provide a way to compose complex types out of simpler ones and allow you to write more modular and reusable code.
Example: Basic Embedded Struct
package main
import (
"fmt"
)
type Address struct {
Street string
City string
State string
ZipCode string
}
type Person struct {
Name string
Age int
Address // Embedded struct
}
func main() {
p := Person{
Name: "John Doe",
Age: 30,
Address: Address{ // Initialize fields of the embedded struct
Street: "123 Elm St",
City: "Somewhere",
State: "CA",
ZipCode: "12345",
},
}
// Access fields of the embedded struct directly
fmt.Printf("Name: %s\n", p.Name)
fmt.Printf("Age: %d\n", p.Age)
fmt.Printf("Address: %s, %s, %s, %s\n", p.Street, p.City, p.State, p.ZipCode)
}
Example: Methods in Embedded Structs
You can also define methods on both the outer struct and the embedded struct:
package main
import (
"fmt"
)
type Address struct {
Street string
City string
State string
ZipCode string
}
func (a Address) FullAddress() string {
return fmt.Sprintf("%s, %s, %s, %s", a.Street, a.City, a.State, a.ZipCode)
}
type Person struct {
Name string
Age int
Address // Embedded struct
}
func (p Person) FullDetails() string {
return fmt.Sprintf("Name: %s, Age: %d, Address: %s", p.Name, p.Age, p.FullAddress())
}
func main() {
p := Person{
Name: "John Doe",
Age: 30,
Address: Address{ // Initialize fields of the embedded struct
Street: "123 Elm St",
City: "Somewhere",
State: "CA",
ZipCode: "12345",
},
}
// Access methods of the embedded struct and the outer struct
fmt.Println(p.FullDetails())
}
Example: Multiple Embedded Structs
A struct can embed multiple other structs. Here’s an example:
package main
import (
"fmt"
)
type Address struct {
Street string
City string
State string
ZipCode string
}
type Contact struct {
Email string
Phone string
}
type Person struct {
Name string
Age int
Address // Embedded struct
Contact // Another embedded struct
}
func main() {
p := Person{
Name: "John Doe",
Age: 30,
Address: Address{ // Initialize fields of the embedded struct
Street: "123 Elm St",
City: "Somewhere",
State: "CA",
ZipCode: "12345",
},
Contact: Contact{
Email: "john@example.com",
Phone: "123-456-7890",
},
}
// Access fields of the embedded structs directly
fmt.Printf("Name: %s\n", p.Name)
fmt.Printf("Age: %d\n", p.Age)
fmt.Printf("Address: %s, %s, %s, %s\n", p.Street, p.City, p.State, p.ZipCode)
fmt.Printf("Email: %s\n", p.Email)
fmt.Printf("Phone: %s\n", p.Phone)
}
Explanation
-
Basic Embedded Struct:
- The
Personstruct includesAddressas an embedded struct. - Fields of
Addresscan be accessed directly as if they were fields ofPerson.
- The
-
Methods in Embedded Structs:
- The
Addressstruct has aFullAddressmethod. - The
Personstruct has aFullDetailsmethod that calls theFullAddressmethod. - Both methods can be accessed directly on a
Personinstance.
- The
-
Multiple Embedded Structs:
- The
Personstruct includes bothAddressandContactas embedded structs. - Fields from both
AddressandContactcan be accessed directly on aPersoninstance.
- The
Using embedded structs is an efficient way to modularize your code and promote reuse while maintaining a simple and intuitive syntax. It is a powerful feature in Go that combines the concepts of composition and inheritance.