Go中的interface

263 阅读2分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

interface

接口是一种数据类型, Go语言中的所有类型都默认实现了空接口, 因此, 一个空接口类型的变量可以存储任意类型的值

一个接口类型的变量, 零值为nil

定义一个接口变量

 // 定义一个接口类型的变量
 var i interface{};
 ​
 // 接口类型变量的零值为nil
 fmt.Printf("%#v \n", i)
 ​
 // 一个接口类型的变量, 可以存储任何类型的值
 // 存储整型
 i = 3
 fmt.Println("类型: ", reflect.TypeOf(i), "值: ", i)
 ​
 // 存储浮点型
 i = 3.14
 fmt.Println("类型: ", reflect.TypeOf(i), "值: ", i)
 ​
 // 存储字符串
 i = "hi, shaosiming"
 fmt.Println("类型: ", reflect.TypeOf(i), "值: ", i)
 ​
 // 存储结构体
 type Person struct {
    name string
    age int
 }
 ​
 i = Person{name: "shaosiming", age: 18}
 fmt.Println("类型: ", reflect.TypeOf(i), "值: ", i)

使用接口中的方法

 // 创建一个老师, 并调用它的方法
 t := Teacher{"shaosiming"}
 t.eat()
 t.sleep()
 ​
 // 创建一个学生, 并调用它的方法
 s := Student{"yuer"}
 s.eat()
 s.sleep()
 ​
 // 声明一个接口类型, 并为它赋值
 var p Personer
 ​
 fmt.Println("为接口变量赋值老师结构体")
 p = t
 p.eat()
 p.sleep()
 ​
 p = s
 fmt.Println("为接口变量赋值学生结构体")
 p.eat()
 p.sleep()

接口的嵌入

 // 接口的嵌入
 type Reader interface {
    read()
 }
 ​
 type Writer interface {
    write()
 }
 ​
 // 一个接口可以嵌入另一个接口, 只需要实现另一个接口中的所有方法
 type IoOperater interface {
    Reader
    Writer
    open()
    close()
 }

类型断言

 /*
 我们可以把老师或者学生结构体类型的变量赋值给Personer接口类型的变量
 那么通过Personer接口类型的变量, 如何知道具体的变量类型, 类型断言来干这个事情
 */
 value, ok := p.(Teacher)
 // 如果ok为false, 则说明断言失败
 if ok {
    fmt.Println("p中存储的数据类型为老师类型: ", value)
 }
 ​
 value2, ok := p.(Student)
 // 如果ok为true, 则说明断言成功, value2则为转换成功后的Student类型的值
 if ok {
    fmt.Println("p中存储的数据类型为学生类型: ", value2)
 }
 ​
 // 使用switch语句断言
 var value3 interface{} = p
 switch str := value3.(type) {
 case Student:
    fmt.Println("p类型为学生类型: ", str)
 case Teacher:
    fmt.Println("p类型为老师类型: ", str)
 default:
    fmt.Println("我也不知道什么类型了")
 }

类型检查

 // 类型检查
 var value4 interface{} = t
 value5, ok := value4.(Teacher)
 if ok {
    fmt.Printf("value类型断言结果为:%T\n", value5)
 } else {
    fmt.Printf("value不是Teacher类型 \n")
 }

接口的继承

 // 接口的继承, 一个接口可以包含其它多个接口, 实现多重继承
 type MyReaderWriter interface {
    io.Reader
    io.Writer
    io.Closer
 }

总结

任何类型如果实现了某个接口中的所有方法, 也就隐式实现了这个接口

Go中的接口降低了代码的耦合度, 改善了代码的复用性, 可以让我们设计出更优秀的架构

Go中没有类的概念, 因此不需要维护传统的面向对象语言中类的层次结构

Go中的接口包罗万象, 灵活使用接口这个类型, 相信可以写出更优雅的Go代码!!!