Chapter 12 of 20
Interfaces
Implicit implementation, the empty interface, type assertions
Interface Definition and Implicit Implementation
Go interfaces are defined by a method set; a type implements an interface automatically as long as it has every method in the set — no implements keyword.
package main
import "fmt"
type Stringer interface {
String() string
}
type User struct{ Name string }
func (u User) String() string { return "User(" + u.Name + ")" }
func main() {
var s Stringer = User{"Alice"}
fmt.Println(s.String())
}The Empty Interface and any
interface{} has no methods, so every type satisfies it. Since Go 1.18, any is a built-in alias for it.
package main
import "fmt"
func Print(v any) { fmt.Println(v) }
func main() {
Print(1)
Print("hi")
Print([]int{1, 2})
}Type Assertions and type switch
package main
import "fmt"
func describe(v any) {
switch x := v.(type) {
case int:
fmt.Println("int", x)
case string:
fmt.Println("string", x)
default:
fmt.Printf("%T %v\n", x, x)
}
}
func main() {
describe(42)
describe("hi")
describe(3.14)
}Interface Design Tips
- The smaller the interface the better: the standard library's io.Reader and io.Writer each have just one method
- Interfaces are defined by the consumer, not "declared as implemented" by the implementer
- Return concrete types, accept interfaces (accept interfaces, return structs)