首页 > Go学习 > Go语言中的接口
2021
09-08

Go语言中的接口

接口是一组方法的集合,定义了实例的行为

任何其他类型只要全部实现了这些方法就是实现了这个接口

既然接口定义了实例的行为,那么就意味着接口必须赋值一个实例,这个实例才能使用接口中的方法

每一个接口都包含两个属性,一个是值,一个是类型

定义接口

type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   ...
   method_namen [return_type]
}

以下为一个实现接口的实例

type Human interface {
    eat(food string) string
    sleep()
}
//定义一个human接口

type People struct {
    name string
}
//定义一个结构体

func (who People) eat(food string) string {
    fmt.Println(me.name,"吃",food)
    return "吃饱了"
}
func (who People) sleep() {
    fmt.Println(me.name,"睡觉")
}
//实现接口所有方法并绑定到People结构体的who实例变量上


func main() {
    var me Human
    //声明一个要实现接口的变量
    me = People {name:"三千"}
    //给接口赋值,让值绑定接口
    //上面两句可以直接使用一句
    //var me Human = People {name:"三千"}
    fmt.Println(me.eat("面条"))
    me.sleep()
}

上面程序运行后会显示:
三千 吃 面条
吃饱了
三千 睡觉

空接口

空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法

可以说所有类型都至少实现了空接口,也就是说空接口可以赋予任何类型的值

一个空接口的值和类型都是nil

使用空接口

空接口不需要我们额外声明,直接使用interface{}就表示一个空接口
var demo interface{}

demo = 5
demo = "hello"
demo = true
一个空接口可以赋予任何类型的值

函数接受任意类型的值

func demo (face interface{}) interface{}{
    fmt.Println(face)
    return face
}
该函数可以接受一个任意类型的值,并返回一个任意类型的值
使用func demo (faces ...interface{})可以接受任意个任意类型的值

切片或数组接受任意类型

var any = make([]interface{},10)

当空接口承载数组或切片后,该对象无法再进行切片arr[start_index:end_index]

断言类型(Type Assertion)

断言类型的格式:变量.(type_name)

会返回两个值,第一个是变量的值,第二个是断言类型的结果(bool值),第二个值不一定有变量接收

首先判断变量的值是否非nil
然后判断变量的值是否是type_name类型
两个条件都通过会返回变量的值和true
有一个条件不通过会返回type_name的默认值和false

当断言类型失败时
如果有变量(可以是_)接收第二个返回值(false)则正常运行
如果没有变量接受会触发panic

主要判断一个空接口中存储的值

var demo interface{} = "hello"
var a = demo.(string)
var b,ok = demo.(int)
var c = demo.(int)
变量a由于断言成功被赋值"hello"
变量b断言失败但是有ok变量接受false,所以会被赋值空字符串""
变量c初始化时由于断言失败会触发panic

静态类型和动态类型

静态类型(static type)

就是声明变量时的类型,是编码代码时就确定的,如var demo int

动态类型(concrete type)

也叫具体类型,是程序运行时系统才能看见的类型

var demo interface{}

demo = 5
demo = "hello"

以上代码中在声明变量demo时指定了变量为interface{}类型,所以demo的静态类型就是interface{},这个是在编写代码的时候就确定的。

后面我们又给demo变量赋值int类型5,此时它的静态类型还是interface{},这是不会变的,但是它的动态类型此时变成了int类型

同理,我们给变量赋值string类型"hello",此时它的静态类型还是interface{},它的动态类型此时又变成了string类型

无论是demo=5还是demo="hello",都是当程序运行到这里时,变量的类型,才发生了改变
最后编辑:
作者:qingheluo
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。