🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> go语言接口(interface),类似其他语言的接口的作用,主要用于定义一组函数(方法)签名,不包括实现。 [TOC] ## 接口定义 > 语法 ~~~ type 接口类型名 interface {     函数签名列表 } ~~~ > 例子 ~~~ // 定义Book接口类型,里面包含一个Abs函数签名定义,不包括函数实现。 type Book interface {     Abs() float64 } ~~~ ## 接口实现 > go语言实现接口,采用的是隐式实现方式,并不像java那样需要显示的implement接口,只需实现了接口中的方法,就认为实现了该接口 ~~~ package main import ( "fmt" ) // 定义Book接口类型,里面包含一个Abs函数签名定义,不包括函数实现 type Book interface { Abs() float64 } // 定义一个MyFloat类型,它是float64的别名 type MyFloat float64 // 给MyFloat类型,定义一个Abs方法,计算绝对值 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } // 定义ArtBook类型结构体 type ArtBook struct { Price1, Price2 float64 } // 为ArtBook类型定义Abs方法 func (book *ArtBook) Abs() float64 { return book.Price1 + book.Price2 } func main() { // 定义Book接口变量 var book Book // 定义MyFloat类型变量 f := MyFloat(-100.25) // 因为MyFloat实现了,Book接口中定义的方法,所以可以赋值给接口类型变量 book = f // 通过接口类型调用方法 fmt.Println(book.Abs()) // 定义ArtBook类型变量 v := ArtBook{Price1: 11, Price2: 20} // 将ArtBook变量赋值给接口类型,这里之所以需要取地址符,因为*ArtBook类型实现了接口的Abs方法 book = &v // 通过接口类型调用方法 fmt.Println(book.Abs()) } ~~~ > MyFloat和ArtBook并没有显式的说明实现Book接口,只要实现了Book接口的方法,就认为实现了该接口 ## 接口变量默认值 > 没有初始化的接口变量,默认值是nil ~~~ var book Book if book == nil { fmt.Println("is nil") } fmt.Println(book) ~~~ ## 空接口 > 包含0个方法的接口,就是空接口,如下 ~~~ interface{} ~~~ ### 空接口类型 > 空接口类型可以存储任意类型的数据,类似java的object类型 ``` package main import "fmt" func main() { // 定义空接口变量 var obj interface{} // 赋值一个Int类型数据给空接口 obj = 42 fmt.Println(obj) // 再赋值一个string类型数据给空接口 obj = "hello" fmt.Println(obj) } ``` ### interface类型转换 > 转换语法:i 是interface{}类型变量,T是我们要转换的类型 ``` t := obj.(要转换的类型) ``` > 例子 > 注意:interface{}类型转换,只能转换至真实的类型,通俗的讲就是,当初赋值给interface{}变量的是什么类型数据,就只能还原成什么类型数据 ``` // 定义一个interface{}类型,并初始化为字符串 var obj interface{} = "hello" // 转换成string类型 s := obj.(string) ``` ### 判断Interface类型转换失败 > 语法:通过第二个返回值ok判断是否转换成功 ``` value, ok := obj.(要转换的类型) ``` > 例子 ``` var obj interface{} = "hello" str, ok := obj.(string) ``` ### interface类型判断 > 通过switch语句结合i.(type)语法,判断interface类型 ``` package main import "fmt" func do(obj interface{}) { // 通过switch判断i的类型 switch v := obj.(type) { case int: fmt.Println("是int类型,", v) case string: fmt.Println("是string类型,", v) default: fmt.Println("未知类型,", v) } } func main() { do(21) do("hello") do(true) } ```