go · level 3 · unit 7 · lesson 3
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
Embed a type in a struct and its methods come along too.
Write a type inside a struct with no field name, and you are it. type Server struct { Logger; name string } gives every Server a Logger inside. Its fields and methods are : s.Log("hi") works as if Server had its own Log.
It is not inheritance. A Server is not a Logger; it has one, and s.Log is shorthand for s.Logger.Log. If Server defines a Log of its own, that one wins, and the embedded one is still there as s.Logger.Log.
A favourite use is embedding sync.Mutex beside the data it guards, so c.Lock() and c.Unlock() read naturally.
package main
import "fmt"
type Logger struct {
prefix string
}
func (l Logger) Log(msg string) {
fmt.Println(l.prefix + msg)
}
type Server struct {
Logger
name string
}
func main() {
s := Server{Logger: Logger{prefix: "[web] "}, name: "shop"}
s.Log("starting " + s.name)
s.Logger.Log("the same method, the long way round")
fmt.Println("prefix is", s.prefix)
} The embedded field's name is its type's name, so you set it with Logger: Logger{...}.
guess first
Both types have a Speak method. What prints?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
package main
import "fmt"
type Animal struct{ Name string }
func (a Animal) Speak() string { return a.Name + " makes a sound" }
type Dog struct {
Animal
}
func (d Dog) Speak() string { return d.Name + " barks" }
func main() {
d := Dog{Animal{Name: "Rex"}}
fmt.Println(d.Speak())
fmt.Println(d.Animal.Speak())
}
your turn
Your turn. Embed a mutex in a tally.
Embed the Mutex from sync, fill in the method that unlocks it, and add one more drink to the order.
output
press run to see what happens
fix it
The server cannot find its Log. Can you fix it?
output
press run to see what happens
- Read the error:
Serverhas no field or methodLog. Is theLoggerreally embedded? logger Loggeris an ordinary named field. Only a type with no field name is embedded and promoted.- Write the field as plain
Logger, and set it withLogger: Logger{prefix: "[web] "}.
nailed it
your types are built from smaller ones. :D
- An embedded type has no field name.
- Its fields and methods are promoted to the outer struct.
- It is not inheritance, and an outer method wins.
new words in your collection
- embedding
- promoted
This lesson isn’t saved. A free account remembers every lesson you finish.