package main
import "fmt"
// 定义Animal接口
type Animal interface {
Speak() string
}
// Dog结构体实现Animal接口
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return fmt.Sprintf("Woof! I'm %s", d.Name)
}
// Cat结构体实现Animal接口
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return fmt.Sprintf("Meow! I'm %s", c.Name)
}
func main() {
// 正确初始化Dog实例并赋值给Animal接口
var dog Dog = Dog{Name: "Buddy"}
var animal1 Animal = dog
fmt.Println(animal1.Speak())
// 正确初始化Cat实例并赋值给Animal接口
var cat Cat = Cat{Name: "Whiskers"}
var animal2 Animal = cat
fmt.Println(animal2.Speak())
// 类型断言确保安全转换
if dog, ok := animal1.(Dog); ok {
fmt.Printf("It's a dog named %s\n", dog.Name)
} else {
fmt.Println("Not a dog")
}
if cat, ok := animal2.(Cat); ok {
fmt.Printf("It's a cat named %s\n", cat.Name)
} else {
fmt.Println("Not a cat")
}
}
- 接口实现:首先定义
Animal
接口以及实现该接口的Dog
和Cat
结构体。
- 初始化:分别创建
Dog
和Cat
的实例,并将它们赋值给Animal
接口类型的变量。这一步在Go语言中是安全的,因为Go语言的接口实现是隐式的,只要结构体实现了接口的所有方法,就可以赋值给该接口类型。
- 类型断言:在需要将接口类型转换回具体结构体类型时,使用类型断言
value, ok := interfaceValue.(type)
的形式,ok
为true
时表示转换成功,从而避免panic
。