Golang 中的接口类型(interface type)和具体类型(concrete type)有什么区别?

在 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 接口。

所以接口类型具有以下特点:

  1. 接口类型不代表任何具体的值,它只是一个方法签名的集合。
  2. 任何具体类型实现接口中的所有方法,就实现了该接口。
  3. 可以通过接口类型调用方法,而不需要知道具体类型。这体现了依赖倒置原则。
  4. 接口可以作为函数的参数类型或返回值类型。

相比之下,具体类型有以下特点:

  1. 代表一块具体的内存,里面存储着具体的值。
  2. 有具体的实现方法和字段。
  3. 可以直接实例化使用。

接口的主要作用有:

  1. 隐藏具体实现,抽象行为。
  2. 可以对不同具体类型的对象执行相同的操作。
  3. 可以实现解耦,减少依赖。
  4. 可以模拟多态等行为。

所以总结来说,接口类型表示一种行为规范,具体类型才代表真正的实现。 Golang 的接口机制非常灵活和强大,它是 Golang 设计理念中“组合优于继承”的重要体现,也是实现解耦和灵活设计的重要手段。