关于Go语言的接口值
GO语言的接口值
Go语言中,一个接口的值有两个部分:具体类型和该类型的一个值。e二者称为动态类型和动态值
接口类型的零值
在Go中,变量总是初始化为一个特定的值,接口的零值就是它的动态类型和值都设置为nil
var w io.Writer
fmt.Println(reflect.TypeOf(w), w)
这段代码运行结果为
PS D:\chengxu\test\go> go build .\main.go | .\main.exe
<nil> <nil>
如果把一个具体类型赋给一个接口类型,那这个接口类型变量变为具体类型,值也变为具体类型的值
var w io.Writer
fmt.Println(reflect.TypeOf(w), w)
w = os.Stdout
fmt.Println(reflect.TypeOf(w), w)
运行结果为
PS D:\chengxu\test\go> go build .\main.go | .\main.exe
<nil> <nil>
*os.File &{0xc0000d0280}
如果一个接口被重新被赋值nil,那么他的动态类型和动态值重新都变为nil。
var w io.Writer
fmt.Println(reflect.TypeOf(w), w)
w = os.Stdout
fmt.Println(reflect.TypeOf(w), w)
w = nil
fmt.Println(reflect.TypeOf(w), w)
结果为
PS D:\chengxu\test\go> go build .\main.go | .\main.exe
<nil> <nil>
*os.File &{0xc00010e280}
<nil> <nil>
含有空指针的非空接口
有一种特殊情况,接口值得类型不为nil,而他的动态值为nil
func main() {
var buf *bytes.Buffer
f(buf)
}
func f(out io.Writer) {
if out != nil {
out.Write([]byte("done\n"))
}
}
在这种情况下,类型为*bytes.Buffer的空指针被赋给了out参数,所以out的动态值为nil,动态类型为 *bytes.Buffer,而在检查 **out != nil ** 中,它会通过,因为只有当一个接口类型值得两个部分都为nil时,它 == nil的结果才会使false。