在 Golang 中,接口类型和具体类型是两个不同的类型:
- 具体类型(concrete type):像 int、string、bool 等这些类型就是具体类型,它们代表一块具体的内存,里面存储着具体的值。
- 接口类型(interface type):接口类型是一组方法签名的集合,它并不代表一块具体的内存。任何具体类型实现了接口中的所有方法,就实现了该接口。
例如:
type Sayer interface {
Say()
}
type Dog struct {}
func (d Dog) Say() {
fmt.Println("汪汪汪!")
}
func Say(s Sayer) {
s.Say() // 调用Say方法
}
func main() {
var s Sayer // s是接口类型
s = Dog{} // 具体类型Dog实现了Sayer接口
Say(s) // 汪汪汪!
}
这里 Dog 是具体类型,Sayer 是接口类型。我们可以将 Dog 类型的变量赋值给 Sayer 类型的变量,因为 Dog 实现了 Sayer 接口。
所以接口类型具有以下特点:
- 接口类型不代表任何具体的值,它只是一个方法签名的集合。
- 任何具体类型实现接口中的所有方法,就实现了该接口。
- 可以通过接口类型调用方法,而不需要知道具体类型。这体现了依赖倒置原则。
- 接口可以作为函数的参数类型或返回值类型。
相比之下,具体类型有以下特点:
- 代表一块具体的内存,里面存储着具体的值。
- 有具体的实现方法和字段。
- 可以直接实例化使用。
接口的主要作用有:
- 隐藏具体实现,抽象行为。
- 可以对不同具体类型的对象执行相同的操作。
- 可以实现解耦,减少依赖。
- 可以模拟多态等行为。
所以总结来说,接口类型表示一种行为规范,具体类型才代表真正的实现。 Golang 的接口机制非常灵活和强大,它是 Golang 设计理念中“组合优于继承”的重要体现,也是实现解耦和灵活设计的重要手段。