package main import "fmt" // 1. 接口只约定需要什么方法,不规定结构体有哪些字段。 type Introducer interface { Introduce() string } type Student struct { Name string } // 方法签名符合接口要求,Student 就自动实现 Introducer。 func (student Student) Introduce() string { return "我是学生:" + student.Name } type Teacher struct { Name string Subject string } func (teacher Teacher) Introduce() string { return fmt.Sprintf("我是老师:%s,教授%s", teacher.Name, teacher.Subject) } // 2. 函数依赖接口,不限定必须传 Student 或 Teacher。 // 调用方负责传入可正常使用的实现,而不是 nil。 func introduction(person Introducer) string { return person.Introduce() } // 3. 指针接收者示例:只有 *Assistant 实现这个接口。 type Assistant struct { Name string } func (assistant *Assistant) Introduce() string { // 本方法特意支持 nil 指针,其他实现不一定支持。 if assistant == nil { return "助教信息为空" } return "我是助教:" + assistant.Name } func main() { fmt.Println("=== 不同类型实现同一个接口 ===") student := Student{Name: "小朱"} teacher := Teacher{Name: "王老师", Subject: "Go"} fmt.Println(introduction(student)) fmt.Println(introduction(teacher)) fmt.Println("\n=== 接口变量与动态类型 ===") var person Introducer = student fmt.Printf("实际类型:%T,介绍:%s\n", person, person.Introduce()) person = teacher fmt.Printf("实际类型:%T,介绍:%s\n", person, person.Introduce()) fmt.Println("\n=== 接口切片 ===") people := []Introducer{student, teacher, &Assistant{Name: "小陈"}} for _, item := range people { fmt.Println(introduction(item)) } fmt.Println("\n=== 接口与 nil ===") var empty Introducer fmt.Printf("未赋值接口为 nil:%t\n", empty == nil) // empty.Introduce() // 没有实际实现,调用会 panic。 var assistant *Assistant person = assistant // 保存了具体类型 *Assistant,即使其中的指针值为 nil。 fmt.Printf("保存 nil 指针后,接口为 nil:%t\n", person == nil) fmt.Println(person.Introduce()) }