Core Concepts
Structs and Interfaces
Build complex types with Go structs and define behavior with interfaces.
Structs
Go uses structs instead of classes. Methods can be attached to any type.
Methods
Methods are functions with a receiver argument. Pointer receivers allow modification of the struct.
Interfaces
Go interfaces are implicitly satisfied — no implements keyword needed. If a type has all the methods an interface requires, it satisfies the interface automatically.
This is a powerful form of duck typing with static type checking.
Embedding
Go uses composition through embedding instead of inheritance.
Example
go
package main
import (
"fmt"
"math"
)
// Struct
type Rectangle struct {
Width float64
Height float64
}
type Circle struct {
Radius float64
}
// Methods with value receiver (read-only)
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
// Method with pointer receiver (can modify struct)
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius
}
// Interface - implicitly satisfied
type Shape interface {
Area() float64
Perimeter() float64
}
func printShapeInfo(s Shape) {
fmt.Printf("Area: %.2f, Perimeter: %.2f\n", s.Area(), s.Perimeter())
}
// Embedding (composition over inheritance)
type Animal struct {
Name string
}
func (a Animal) Speak() string {
return a.Name + " says..."
}
type Dog struct {
Animal // embed Animal
Breed string
}
func (d Dog) Speak() string {
return d.Name + " says: Woof!"
}
func main() {
r := Rectangle{Width: 5, Height: 3}
c := Circle{Radius: 4}
printShapeInfo(r) // Works! Rectangle satisfies Shape
printShapeInfo(c) // Works! Circle satisfies Shape
r.Scale(2)
fmt.Printf("Scaled: %.0f x %.0f\n", r.Width, r.Height)
// Polymorphism with interface slice
shapes := []Shape{
Rectangle{Width: 3, Height: 4},
Circle{Radius: 5},
}
for _, s := range shapes {
fmt.Printf("%.2f\n", s.Area())
}
// Embedding
dog := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
fmt.Println(dog.Speak()) // Rex says: Woof!
fmt.Println(dog.Name) // Accessing embedded field
}Try it yourself — GO