空接口

空接口

  • 基本概念

    • 没有任何方法的接口称为空接口,空接口表示为 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
        }
    • 从 eface 的数据结构可以看出,空接口不是真的为空,其保留了具体实例的类型和值拷贝
    • 即便存放的具体类型是空的,空接口也不是空的
    • 由于空接口自身没有方法集,所以空接口变量实例化后的真正用途不是接口方法的动态调用
    • 空接口在 Go 语言中真正的意义是支持多态
      • 有如下几种方式使用了空接口(将空接口类型还原)
        • 1、通过接口类型断言
        • 2、通过接口类型查询
        • 3、通过反射
原文地址:https://www.cnblogs.com/jcjc/p/12511163.html