golang学习笔记5——接口
Posted yubo_725
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang学习笔记5——接口相关的知识,希望对你有一定的参考价值。
接口的声明
golang中的接口声明方式如下:
type 接口名 interface
方法名(参数) 返回值
例子:
// Writer接口
type Writer interface
// Write方法,参数为一个字符串
Write(s string)
// Stringer接口
type Stringer interface
// String方法,参数为空,返回值为string
String() string
接口的实现
golang中实现接口需要满足两个条件:
- 某个类型实现了与接口中的方法具有相同签名的方法
- 接口中的方法全部都被某个类型实现
只有同时满足上面两条,才算某个接口被某个类型实现,下面举例说明:
// 定义一个Animal接口,接口中包含Sleep和Eat两个方法
type Animal interface
Sleep()
Eat(string)
// 定义一个Dog结构体
type Dog struct
// Dog实现Animal的Sleep方法
func (d *Dog) Sleep() // (1)
fmt.Println("dog is sleeping...")
// Dog实现了Animal的Eat方法
func (d *Dog) Eat(food string)
fmt.Printf("dog is eating %s\\n", food)
func main()
// 声明一个Animal接口
var anim Animal
// 初始化一个Dog结构体
d := new(Dog)
// 将Dog赋值给anim
anim = d // (2)
fmt.Printf("%T\\n", d) // 打印: *main.Dog
fmt.Printf("%T\\n", anim) // 打印: *main.Dog
上面的代码展示了Dog
结构体实现Animal
接口的方法,如果将Dog
结构体的Sleep
方法增加一个参数,那Dog
的Sleep
方法签名就与Animal
接口中定义的Sleep
方法签名不一致,则Dog
就不算实现了Animal
接口。
例如把上面的代码注释(1)
这行修改为如下代码:
func (d *Dog) Sleep(s string)
则以上代码的注释(2)
这行会报错,因为Sleep
方法的签名不一致,所以Dog
没有实现Animal
接口,则无法将d
赋值给anim
变量
接口与类型
关于接口和类型,有如下几点需要说明:
- 一个类型可以实现多个接口
- 一个接口可以被多个类型实现
如下代码所示:
type Door interface
OpenDoor()
CloseDoor()
type Window interface
OpenWin()
CloseWin()
// 房子
type House struct
// 别墅
type Villa struct
// 房子实现了OpenDoor方法
func (h *House) OpenDoor()
fmt.Println("house open door...")
// 房子实现了CloseDoor方法
func (h *House) CloseDoor()
fmt.Println("house close door...")
// 别墅实现了OpenDoor方法
func (v *Villa) OpenDoor()
fmt.Println("open villa door...")
// 别墅实现了CloseDoor方法
func (v *Villa) CloseDoor()
fmt.Println("close villa door...")
接口的嵌套组合
type Writer interface
Write(string)
type Reader interface
Read() string
// 接口的嵌套组合
type ReadWriter interface
Reader
Writer
// Machine实现了ReadWriter接口
type Machine struct
func (m *Machine) Write(s string)
fmt.Println("machine write " + s)
func (m *Machine) Read() string
return "hello"
func main()
var readWriter ReadWriter
var reader Reader
machine := new(Machine)
machine.Write("haha")
readWriter = machine
reader = machine
s := readWriter.Read()
fmt.Println(s)
reader = machine
reader.Read()
接口的转换
举例:鸟和猪都能行走,但鸟可以飞而猪不行,分别定义两个接口:Flyer
Walker
,鸟需要实现这两个接口,而猪只实现Walker
接口,怎么判断一个变量是Flyer
或者Walker
呢?golang中使用如下方式判断:
f, ok := i.(T)
解释:
i
表示一个接口变量T
表示这个接口要转换成的类型- 如果
i
是T
类型的变量,则f
表示i转换成功后的变量,ok
为true
,如果转换失败,则ok
为false
下面用代码说明:
type Flyer interface
Fly()
type Walker interface
Walk()
type Bird struct
func (b *Bird) Fly()
fmt.Println("bird fly...")
func (b *Bird) Walk()
fmt.Println("bird walk...")
type Pig struct
func (p *Pig) Walk()
fmt.Println("pig walk...")
func main()
// 数组中装了鸟类和猪类
objs := []interfacenew(Bird), new(Pig)
// 遍历数组
for _, item := range objs
// 判断元素是否是Flyer
f, canFly := item.(Flyer)
// 判断元素是否是Walker
w, canWalk := item.(Walker)
if canFly
// 是Flyer则调用Fly()
f.Fly()
if canWalk
// 是Walker则调用Walk()
w.Walk()
打印结果为:
bird fly...
bird walk...
pig walk...
另外接口也可以转为指针类型,比如下面的代码将一个Walker
接口变量转为Pig
指针:
p := new(Pig)
var walker Walker = p
// 将接口转为指针类型
ptr, ok := walker.(*Pig)
if ok
ptr.Walk()
空接口
golang中使用interface
表示空接口,空接口可以表示任何类型的数据,类似于Java
中的Object
类型,在golang中,空接口可以被赋值为任意类型的值,但反之则不行,例如下面的代码:
// obj是空接口,使用interface表示空接口类型
var obj interface
// 将整型值赋值给空接口
var a int = 1
obj = a
fmt.Println(obj)
// 将字符串赋值给空接口
s := "hello"
obj = s
fmt.Println(obj)
// 下面的代码报错,不能将空接口赋值给一个字符串
// var str string = obj
下面的代码实现了将任意类型的数据存到map
中:
// 定义一个map,其中的键值可以是任意类型
var data = make(map[interface]interface)
data["name"] = "zhangsan"
data[1] = 3.14
data[2.5] = &struct
Name string
Color string
Name: "kenny",
Color: "black",
fmt.Println(data)
以上是关于golang学习笔记5——接口的主要内容,如果未能解决你的问题,请参考以下文章