空接口
-
基本概念
- 没有任何方法的接口称为空接口,空接口表示为 interface{}、系统中热河类型都符合空接口的要求
-
空接口的用途
- 空接口和泛型
- Go 语言没有泛型,如果一个函数需要接受任意类型的参数,则参数类型可以使用空接口类型,这是弥补没有泛型的一种手段
- 空接口和发射
- 空接口是发射的基础,反射库就是将相关具体的类型抓换并赋值给空接口后才去处理
- 空接口和泛型
-
空接口和 nil
-
空接口不是真的为空,接口有类型和值两个概念
-
下面举个简单的例子:
-
package main import "fmt" type Inter interface { Pint() Pang() } type St struct { } func (St) Ping() { fmt.Println("pint") } func (*St) Pang() { fmt.Println("pang") } func main() { var st *St = nil var it Inter = st fmt.Println("%p ", st) fmt.Println("%p ", it) if it != nil { it.Pang() // 下面语句会报导致 panic // 方法转换为函数调用,第一个参数是 St类型,由于是 *St 是 nil, 无法获取指针所致的 // 对象值,所以导致 panic // it.Ping() } }
-
程序结果:
- 0x0
- 0x0
- pang
-
这个程序暴露了 Go 语言的一点瑕疵,fmt.Println(“%p ”, it) 的结果是 0x0,但 it != nil 的判断结果却是 true。
-
空接口有两个字段
- 一个是实例类型
- 另一个是指向绑定实例的指针
- 只有两个都为 nil 时,空接口才为 nil
-
-
空接口的数据结构
- 空接口 interface{} 是没有任何方法集的接口,所以空接口内部不需要维护和动态内存分配相关的数据结构 itab
- 空接口只关心存放的具体类型是什么?具体类型是什么?
- 所以空接口的底层数据类型也很简单
-
空接口
- type eface struct {
_typw *_type
data unsafe.Pointer
}
- type eface struct {
- 从 eface 的数据结构可以看出,空接口不是真的为空,其保留了具体实例的类型和值拷贝
- 即便存放的具体类型是空的,空接口也不是空的
- 由于空接口自身没有方法集,所以空接口变量实例化后的真正用途不是接口方法的动态调用
- 空接口在 Go 语言中真正的意义是支持多态
- 有如下几种方式使用了空接口(将空接口类型还原)
- 1、通过接口类型断言
- 2、通过接口类型查询
- 3、通过反射
- 有如下几种方式使用了空接口(将空接口类型还原)