interface 接口

Interface 接口 #

不包含方法的 interface (empty interface):

type eface struct { // 2 words (16B in 64-bit machine)
	_type *_type
	data  unsafe.Pointer
}

包括方法的 interface:

type iface struct { // 2 words (16B in 64-bit machine)
	tab  *itab
	data unsafe.Pointer
}

必须得类型和值同时都为 nil 的情况下,interface 的 nil 判断才会为 true

有类型但是值为空的 interface 无法被赋值(会 panic),仍然可以调用方法。

示例代码
package main

import (
    "fmt"
    "reflect"
)

type MyError struct {
    Name string
}

func (e *MyError) Error() string {
    return "a"
}

func main() {

    // nil只能赋值给指针、channel、func、interface、map或slice类型的变量 (非基础类型) 否则会引发 panic
    var a *MyError                          // 这里不是 interface 类型  => 而是 一个值为 nil 的指针变量 a
    fmt.Printf("%+v\n", reflect.TypeOf(a))  // *main.MyError
    fmt.Printf("%#v\n", reflect.ValueOf(a)) // a => (*main.MyError)(nil)
    fmt.Printf("%p %#v\n", &a, a)           // 0xc42000c028 (*main.MyError)(nil)
    i := reflect.ValueOf(a)
    fmt.Println(i.IsNil()) // true

    if a == nil {
        fmt.Println("a == nil") //  a == nil
    } else {
        fmt.Println("a != nil")
    }

    fmt.Println("a Error():", a.Error()) //a 为什么 a 为 nil 也能调用方法?(指针类型的值为nil 也可以调用方法!但不能进行赋值操作!如下:)
    // a.Name = "1"           // panic: runtime error: invalid memory address or nil pointer dereference

    var b error = a

    // 为什么 a 为 nil 给了 b 而 b != nil ??? => error 是 interface 类型,type = *a.MyError  data = nil
    fmt.Printf("%+v\n", reflect.TypeOf(b))  // type => *main.MyError
    fmt.Printf("%+v\n", reflect.ValueOf(b)) // data => a == nil
    if b == nil {
        fmt.Println("b == nil")
    } else {
        fmt.Println("b != nil")
    }
    fmt.Println("b Error():", b.Error()) // a
}

References #