95 lines
2.1 KiB
Go
95 lines
2.1 KiB
Go
package main
|
||
|
||
import "fmt"
|
||
|
||
// ========== 1. 定义接口(鸭子类型)==========
|
||
type Speaker interface {
|
||
Speak() string
|
||
}
|
||
|
||
type Dog struct{}
|
||
|
||
func (d Dog) Speak() string {
|
||
return "Woof!"
|
||
}
|
||
|
||
type Cat struct{}
|
||
|
||
func (c Cat) Speak() string {
|
||
return "Meow~"
|
||
}
|
||
|
||
type Robot struct{}
|
||
|
||
func (r Robot) Speak() string {
|
||
return "Beep boop."
|
||
}
|
||
|
||
// ========== 2. 空接口(interface{})==========
|
||
// 在 Go 1.18+ 中,推荐使用 any(它是 interface{} 的别名)
|
||
func printAnything(v any) {
|
||
fmt.Printf("接收到: %v (类型: %T)\n", v, v)
|
||
}
|
||
|
||
// ========== 3. 类型断言 ==========
|
||
func describeSpeaker(s Speaker) {
|
||
fmt.Println("它说:", s.Speak())
|
||
|
||
// 类型断言:判断具体类型
|
||
if d, ok := s.(Dog); ok {
|
||
fmt.Println("这是一只狗!", d)
|
||
} else if c, ok := s.(Cat); ok {
|
||
fmt.Println("这是一只猫!", c)
|
||
}
|
||
}
|
||
|
||
// 使用 switch 进行类型断言(更优雅)
|
||
func identify(v any) {
|
||
switch x := v.(type) {
|
||
case string:
|
||
fmt.Printf("字符串: %s\n", x)
|
||
case int:
|
||
fmt.Printf("整数: %d\n", x)
|
||
case Speaker:
|
||
fmt.Printf("会说话的东西: %s\n", x.Speak())
|
||
default:
|
||
fmt.Printf("未知类型: %T\n", x)
|
||
}
|
||
}
|
||
|
||
// ========== 主函数 ==========
|
||
func main() {
|
||
fmt.Println("=== 1. 鸭子类型:只要会 Speak(),就是 Speaker ===")
|
||
animals := []Speaker{Dog{}, Cat{}, Robot{}}
|
||
for _, a := range animals {
|
||
fmt.Println(a.Speak())
|
||
}
|
||
|
||
fmt.Println("\n=== 2. 空接口(any)可接收任意类型 ===")
|
||
printAnything(42)
|
||
printAnything("Hello")
|
||
printAnything(Dog{})
|
||
|
||
fmt.Println("\n=== 3. 类型断言:从接口还原具体类型 ===")
|
||
describeSpeaker(Dog{})
|
||
describeSpeaker(Cat{})
|
||
|
||
fmt.Println("\n=== 4. 类型 switch:安全高效的类型判断 ===")
|
||
identify("Gopher")
|
||
identify(100)
|
||
identify(Robot{})
|
||
identify(true) // 未知类型
|
||
|
||
fmt.Println("\n=== 5. 安全 vs 不安全的类型断言 ===")
|
||
var i any = "hello"
|
||
s := i.(string) // 不安全:如果类型不对,会 panic
|
||
fmt.Println("不安全断言结果:", s)
|
||
|
||
// 安全方式
|
||
if val, ok := i.(int); ok {
|
||
fmt.Println("是整数:", val)
|
||
} else {
|
||
fmt.Println("不是整数!")
|
||
}
|
||
}
|