Skip to content

接口数据结构

Go Runtime定义了两种接口结构:

1.eface (Empty Interface) —— 空接口 interface{},于表示没有方法的接口(即 any)。因为它不需要查方法表,所以结构简单。

go
type eface struct {
    _type *_type          // 1. 动态类型:指向这个数据的类型信息(它是 int? string? 还是 Dog?)
    data  unsafe.Pointer  // 2. 动态值:指向具体数据的内存地址
}

2.iface (Non-empty Interface) —— 非空接口,用于包含方法的接口。它需要知道怎么调用那些方法

go
type iface struct {
    tab  *itab           // 1. 接口表:包含类型信息 + 方法分发表(函数指针列表)
    data unsafe.Pointer  // 2. 动态值:指向具体数据的内存地址
}

接口nil的判断

题目:

go
func main() {
    var p *int = nil      // 定义一个空的 int 指针
    var i interface{} = p // 把这个空指针赋值给接口

    if i == nil {
        fmt.Println("i 是 nil")
    } else {
        fmt.Println("i 不是 nil")
    }
}

输出:i不是nil, 原因:i == nil 的标准是:Type 和 Data 必须同时为 nil。此时 i 的内部结构是 (*int, nil)。虽然数据是空的,但类型不是空的,所以接口本身不等于 nil。

避坑的写法:

go
// 错误写法
func GetObject() interface{} {
    var p *Object = nil
    return p // 返回了一个 (*Object, nil),判空会失败
}

// 正确写法
func GetObject() interface{} {
    return nil // 返回 (nil, nil)
}

菜就多练

本站访客数 人次 本站总访问量