包含nil指针的接口和nil接口

Tags:

今天看了一段代码,对运行结果十分迷惑,就研究了一番。
package main

import (
    "fmt"
)
type People interface {
    Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func live() People {
    var stu *Student
    return stu
}

func main() m{

    if live() == nil {
        fmt.Println("AAAAAAA", live())
    } else {
        fmt.Println("BBBBBBB", live())
    }

}

运行结果如下

BBBBBBB <nil>

为什么会出现这样的结果,于是开始调试:

package main

import (
	"fmt"
)

type People interface {
	Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func live() People {
	var stu *Student
	return stu
}

func printDynamicType(any interface{}) {
	fmt.Printf("%T\n", any)
}

func main() {
	var a = live()
	printDynamicType(a)
	if live() == nil {
		fmt.Println("AAAAAAA", live())
	} else {
		fmt.Println("BBBBBBB", live())
	}

	var s *Student
	fmt.Println(s == nil)
}

结果是这样的

*main.Student
BBBBBBB <nil>
true

原来将*Student类型的返回值赋值给People时,接口的类型被赋值为Student类型的指针,而类型描述符被赋值为nil。而一个接口为nil的充要条件为接口的运行时类型为nil,并且接口的运行时值为nil。 如果想运行出现之前以为的运行结果,只需把Show方法和live函数里的变量改成非指针类型即可。

package main

import (
	"fmt"
)

type People interface {
	Show()
}

type Student struct{}

func (stu Student) Show() {

}

func live() People {
	var stu Student
	return stu
}

func printDynamicType(any interface{}) {
	fmt.Printf("%T\n", any)
}

func main() {
	var a = live()
	printDynamicType(a)
	if live() == nil {
		fmt.Println("AAAAAAA", live())
	} else {
		fmt.Println("BBBBBBB", live())
	}
}

结果如下:

main.Student
BBBBBBB {}