1.11 接口
接口定义与实现
go
package main
import "fmt"
// 接口定义
type Speaker interface {
Speak() string
}
// 隐式实现
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return "Meow!"
}
// 接口作为参数
func MakeSpeak(s Speaker) {
fmt.Println(s.Speak())
}
// 接口作为返回值
func NewPet(name string) Speaker {
return Dog{Name: name}
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Kitty"}
var s Speaker
s = dog
fmt.Println(s.Speak()) // Woof!
s = cat
fmt.Println(s.Speak()) // Meow!
// 接口切片
pets := []Speaker{dog, cat}
for _, pet := range pets {
pet.Speak()
}
}空接口
go
package main
import "fmt"
func main() {
// 存储任意类型 (Go 1.18+ 推荐用 any 替代 interface{})
var x any
x = 42
x = "hello"
x = true
// 空接口切片
items := []any{1, "hello", true, 3.14}
for i, item := range items {
fmt.Printf("%d: %v (type: %T)\n", i, item, item)
}
// 通用函数
PrintAnything(42)
PrintAnything("hello")
}
func PrintAnything(x any) {
fmt.Printf("Value: %v, Type: %T\n", x, x)
}类型断言与类型开关
go
package main
import "fmt"
func main() {
// 类型断言
var x any = "hello"
s, ok := x.(string)
fmt.Println(s, ok) // hello true
i, ok := x.(int)
fmt.Println(i, ok) // 0 false
// 类型开关
var values []any = []any{"hello", 42, 3.14, true}
for _, v := range values {
switch val := v.(type) {
case string:
fmt.Printf("字符串:%s\n", val)
case int:
fmt.Printf("整数:%d\n", val)
case float64:
fmt.Printf("浮点数:%.2f\n", val)
case bool:
fmt.Printf("布尔:%t\n", val)
default:
fmt.Printf("未知类型:%T\n", val)
}
}
}接口嵌套
go
package main
import "fmt"
// 接口嵌套
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}
type Closer interface {
Close() error
}
type ReadWriteCloser interface {
Reader
Writer
Closer
}
func main() {
// 接口设计原则:
// 1. 接口要小 (单一职责)
// 2. 接受接口,返回结构体
// 3. 接口应该在消费者处定义
// 4. 避免过早抽象
}