// Package runner provides a Runner type that is used to define both RunCounter // and EmbeddedRunCounter to show examples of how to use composition in Go. package runner import "fmt" // A Task is a simple task that prints a message when run. type Task struct{ Msg string } func (t Task) Run() { fmt.Println("running", t.Msg) } // END_TASK OMIT // A Runner provides a way of running tasks. type Runner struct{ name string } func (r *Runner) Name() string { return r.name } func (r *Runner) Run(t Task) { t.Run() } func (r *Runner) RunAll(ts []Task) { for _, t := range ts { r.Run(t) } } // END_RUNNER OMIT // A RunCounter is a Runner that keeps a counter of the run tasks. type RunCounter struct { runner Runner // HL count int } func NewRunCounter(name string) *RunCounter { return &RunCounter{runner: Runner{name}} } func (r *RunCounter) Run(t Task) { r.count++ r.runner.Run(t) // HL } func (r *RunCounter) RunAll(ts []Task) { r.count += len(ts) r.runner.RunAll(ts) // HL } func (r *RunCounter) Count() int { return r.count } func (r *RunCounter) Name() string { return r.runner.Name() }