A slice of interface values can hold different concrete types with shared behavior.

interface slice A slice typed as an interface can store any value that satisfies that interface.

Interface Slices

taskTitle
interface_slice.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

type Describer interface {
	Describe() string
}

type Task struct {
	Title string
}

func (t Task) Describe() string {
	return "task:" + t.Title
}

type User struct {
	Name string
}

func (u User) Describe() string {
	return "user:" + u.Name
}

func main() {
	var taskTitle = "trace"
	items := []Describer{Task{Title: taskTitle}, User{Name: "Ada"}}

	for _, item := range items {
		fmt.Println(item.Describe())
	}
}
package main

import "fmt"

type Describer interface {
	Describe() string
}

type Task struct {
	Title string
}

func (t Task) Describe() string {
	return "task:" + t.Title
}

type User struct {
	Name string
}

func (u User) Describe() string {
	return "user:" + u.Name
}

func main() {
	var taskTitle = "review"
	items := []Describer{Task{Title: taskTitle}, User{Name: "Ada"}}

	for _, item := range items {
		fmt.Println(item.Describe())
	}
}
package main

import "fmt"

type Describer interface {
	Describe() string
}

type Task struct {
	Title string
}

func (t Task) Describe() string {
	return "task:" + t.Title
}

type User struct {
	Name string
}

func (u User) Describe() string {
	return "user:" + u.Name
}

func main() {
	var taskTitle = "ship"
	items := []Describer{Task{Title: taskTitle}, User{Name: "Ada"}}

	for _, item := range items {
		fmt.Println(item.Describe())
	}
}
  1. taskTitle ← "trace", items ← []main.Describer{main.Task{Title:"trace"}, main.User{Name:"Ada"}}

    25func main() {26  var taskTitle→ "trace" = "trace" //@taskTitle="review", "ship"27  items→ []main.Describer{main.Task{Title:"trace"}, main.User{Name:"Ada"}} := []Describer{Task{Title: taskTitle"trace"}, User{Name: "Ada"}}
  2. for _, item := range items

    pass 1 of 2
    29for _, itemmain.Task{Title:"trace"} := range items[]main.Describer{main.Task{Title:"trace"}, main.User{Name:"Ada"}} {30  fmt.Println(itemmain.Task{Title:"trace"}.Describe())31}
  3. func (t Task) Describe() string

    13func (t Task) Describe() string {14  return "task:" + t.Title"trace"15}
  4. fmt.Println(item.Describe())

    29for _, item := range items {30  fmt.Println(itemmain.Task{Title:"trace"}.Describe())31}
    outputtask:trace
  5. for _, item := range items

    pass 2 of 2
    29for _, itemmain.User{Name:"Ada"} := range items[]main.Describer{main.Task{Title:"trace"}, main.User{Name:"Ada"}} {30  fmt.Println(itemmain.User{Name:"Ada"}.Describe())31}
  6. func (u User) Describe() string

    21func (u User) Describe() string {22  return "user:" + u.Name"Ada"23}
  7. fmt.Println(item.Describe())

    29for _, item := range items {30  fmt.Println(itemmain.User{Name:"Ada"}.Describe())31}
    outputuser:Ada
  1. taskTitle ← "review", items ← []main.Describer{main.Task{Title:"review"}, main.User{Name:"Ada"}}

    25func main() {26  var taskTitle→ "review" = "review"27  items→ []main.Describer{main.Task{Title:"review"}, main.User{Name:"Ada"}} := []Describer{Task{Title: taskTitle"review"}, User{Name: "Ada"}}
  2. for _, item := range items

    pass 1 of 2
    29for _, itemmain.Task{Title:"review"} := range items[]main.Describer{main.Task{Title:"review"}, main.User{Name:"Ada"}} {30  fmt.Println(itemmain.Task{Title:"review"}.Describe())31}
  3. func (t Task) Describe() string

    13func (t Task) Describe() string {14  return "task:" + t.Title"review"15}
  4. fmt.Println(item.Describe())

    29for _, item := range items {30  fmt.Println(itemmain.Task{Title:"review"}.Describe())31}
    outputtask:review
  5. for _, item := range items

    pass 2 of 2
    29for _, itemmain.User{Name:"Ada"} := range items[]main.Describer{main.Task{Title:"review"}, main.User{Name:"Ada"}} {30  fmt.Println(itemmain.User{Name:"Ada"}.Describe())31}
  6. func (u User) Describe() string

    21func (u User) Describe() string {22  return "user:" + u.Name"Ada"23}
  7. fmt.Println(item.Describe())

    29for _, item := range items {30  fmt.Println(itemmain.User{Name:"Ada"}.Describe())31}
    outputuser:Ada
  1. taskTitle ← "ship", items ← []main.Describer{main.Task{Title:"ship"}, main.User{Name:"Ada"}}

    25func main() {26  var taskTitle→ "ship" = "ship"27  items→ []main.Describer{main.Task{Title:"ship"}, main.User{Name:"Ada"}} := []Describer{Task{Title: taskTitle"ship"}, User{Name: "Ada"}}
  2. for _, item := range items

    pass 1 of 2
    29for _, itemmain.Task{Title:"ship"} := range items[]main.Describer{main.Task{Title:"ship"}, main.User{Name:"Ada"}} {30  fmt.Println(itemmain.Task{Title:"ship"}.Describe())31}
  3. func (t Task) Describe() string

    13func (t Task) Describe() string {14  return "task:" + t.Title"ship"15}
  4. fmt.Println(item.Describe())

    29for _, item := range items {30  fmt.Println(itemmain.Task{Title:"ship"}.Describe())31}
    outputtask:ship
  5. for _, item := range items

    pass 2 of 2
    29for _, itemmain.User{Name:"Ada"} := range items[]main.Describer{main.Task{Title:"ship"}, main.User{Name:"Ada"}} {30  fmt.Println(itemmain.User{Name:"Ada"}.Describe())31}
  6. func (u User) Describe() string

    21func (u User) Describe() string {22  return "user:" + u.Name"Ada"23}
  7. fmt.Println(item.Describe())

    29for _, item := range items {30  fmt.Println(itemmain.User{Name:"Ada"}.Describe())31}
    outputuser:Ada