在Go语言中接口
interface
是一种类型,一种抽象的类型。
interface
x.(type)
Go语言提倡面向接口编程,每个接口由数个方法组成,接口的格式如下:
type interfaceName interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2
…
}
type
关键字将接口定义为自定义的类型名。
er
结尾// 栗子
type writer interface{
Write([]byte) error
}
下面的栗子中dog、cat 、person
都实现了say()方法,因此在接口sayer
中只要是实现了say()
方法的都可以使用。
package main
import "fmt"
// 接口
type dog struct {}
// 实现方法say()
func (d dog) say(){
fmt.Println("wangwangwang")
}
type cat struct {}
// 实现方法say()
func (c cat) say(){
fmt.Println("miaomiaomiao")
}
type person struct {
name string
}
// 实现方法say()
func (p person) say(){
fmt.Println("aaaa")
}
// 实现接口,关键字interface
// 定义一个抽象的类型,只要实现say()方法,都可以传入接口中,当做sayer类型
type sayer interface {
say()
}
// da 函数,执行接口sayer中的方法say方法
func da(arg sayer) {
arg.say()
}
func main(){
//c1 := cat{} //实例化
//da(c1)
//d1 := dog{}
//da(d1)
//p1 := person{
// name:"xiaoming",
//}
//da(p1)
// 声明sayer接口类型的变量s
var s sayer
c2 := cat{}
s = c2 // 实例化的结果来赋值给s
p2 := person{name:"xiaowangzi"}
s = p2
fmt.Println(s)
}
package main
import "fmt"
type mover interface{
move()
}
type person struct {
name string
age int
}
// 使用值接收者实现接口:类型的值和类型的指针接收者都可以保存在类型变量中
//func (p person) move(){
// fmt.Printf("%s在跑..", p.name)
//}
// 使用指针接收者实现接口
func (p *person) move(){
fmt.Printf("%s在跑..", p.name)
}
func main(){
var m mover
p1 := person{ //person类型的值
name: "小王子",
age: 18, // 逗号不能忘记
}
p2 := &person{
name: "哪吒",
age: 18,
}
//m = p1 使用指针接收者报错:p1是person类型的值
m = p2
m.move()
fmt.Println(m)
}
一个类型可以实现多个接口
多个类型也可以实现同一个接口
package main
import "fmt"
// 接口的嵌套:直接使用接口的名字;或者使用接口实现的方法名字
type animal interface {
mover
sayer
//move()
//say()
}
type mover interface{
move()
}
type sayer {
say()
}
type person struct {
name string
age int
}
func (p *person) move(){
fmt.Printf("%s在跑...\n", p.name)
}
func (p *person) say(){
fmt.Printf("%s在叫...\n", p.name)
}
func main(){
var m mover // 定义mover类型的变量
//p1 := person{
// name: "小王子",
// age: 18,
//}
p2 := &person{
name: "哪吒",
age: 20,
}
m = p2
m.move()
fmt.Println(m)
var s sayer // 定义一个sayer类型的变量
s = p2
s.say()
fmt.Println(s)
var g animal // 定义animal类型的变量
g = p2
g.move()
g.say()
fmt.Println(a)
}
空接口是指没有定义任何方法的接口,任何类型都可以实现空接口。
package main
import "fmt"
// 空接口:接口中没有定义任何需要实现的方法
// 空接口变量可以存储任意值
// 空接口可以作为map的value;可以当做函数的参数
// 一般是不需要提前定义
type do interface {
}
func main(){
var x interface{} // 定义一个空接口
x = "hello" // 存储多种类型的值
fmt.Println(x)
x = 100
fmt.Println(x)
// 空接口作为map的值value
var m = make(map[string] interface{}, 16)
m["name"] = "xiaoming"
m["age"] = 18
m["hobby"] = []string{"篮球", "足球"} // 切片类型
fmt.Println(m)
}
接口值是由一个具体类型
和具体类型的值
两部分组成,分别对应为接口的动态类型
和动态类型的值
。
如何判断空接口中类型的值:使用接口断言
x.(T)
返回的结果中有两个值: