1. 什么是interface
在go中,interface(接口)是一种抽象类型,用于定义某些方法的集合,而不具体实现这些方法。接口允许你指定一个类型应该提供哪些功能,但不关心具体实现是什么。
定义一个接口的基本语法如下:
type InterfaceName interface {Method1(parameters) returnTypeMethod2(parameters) returnType// 其他方法
}
一个简单例子:
package mainimport ("fmt"
)// 定义一个接口 Animal
type Animal interface {Speak() string
}// Dog 类型实现了 Animal 接口
type Dog struct{}func (d Dog) Speak() string {return "Woof!"
}// Cat 类型实现了 Animal 接口
type Cat struct{}func (c Cat) Speak() string {return "Meow!"
}// 一个函数,它接收一个 Animal 接口类型
func animalSound(a Animal) {fmt.Println(a.Speak())
}func main() {var dog Animal = Dog{}var cat Animal = Cat{}animalSound(dog) // 输出: Woof!animalSound(cat) // 输出: Meow!
}
代码中,我们定义了一个接口 Animal,它有一个方法 Speak()
,返回一个字符串。Dog
和 Cat
两个类型都实现了 Animal
接口中的 Speak()
方法。因此在二者分别调用Speak()方法时,会根据自己类型调用对应的函数。从代码中我们可以归纳出接口的几个特点:
1. 方法集合:接口定义了一个方法的集合,任何实现了这个方法集合的类型都被视为实现了这个接口。
2. 隐式实现:Go 语言中的接口不需要显式声明某个类型实现了某个接口,只要该类型实现了接口中声明的所有方法,它就被认为实现了这个接口。
3. 多态性:通过使用接口,Go 语言可以实现多态性,这意味着你可以使用接口类型的变量来引用不同类型的对象,只要它们实现了该接口。
2. 空interface
空interface(interface{})不包含任何的method,正因为如此,所有的类型都实现了空interface。空interface对于描述起不到任何的作用(因为它不包含任何的method),但是空interface在我们需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。
例子如下:
func printValue(v interface{}) {fmt.Println(v)
}func main() {printValue(42) // intprintValue("Hello") // stringprintValue(3.14) // float64printValue(true) // bool
}
可以看到,函数中参数是一个interface,它可以接收任何类型的参数。
3. 嵌入interface
和struct类似,interface也是可以被嵌入的,interface1嵌入到interface2种,则interface2就隐式的包含了interface1的字段。比如io包中的ReadWriter等一系列接口的实现: