nil 接口值在 Golang 中如何工作

leo*_*leo 1 interface go

我有以下代码来测试 golang 接口值何时为 false。

package main

import (
    "fmt"
)

func Foo(x interface{}) {
    fmt.Println("33, x == nil = ", x == nil)
}
func main() {
    var x *int = nil
    fmt.Println("11, x == nil = ", x == nil)

    var a interface{}
    fmt.Println(22, &a, &a == nil, a == nil) // 0xc0000935c0 false true
    Foo(x)
}

Run Code Online (Sandbox Code Playgroud)

结果是

11, x == nil =  true
22 0xc00010a040 false true
33, x == nil =  false
Run Code Online (Sandbox Code Playgroud)

我不明白输出。特别是,我不明白为什么&a不是 nil,因为 a 没有初始化。有谁可以帮我解释一下结果吗?谢谢。

Ash*_*rva 8

在 Go 中,当涉及到接口 nil 值时,你需要记住两点:

  1. 根本不包含任何值的 nil 接口值与包含恰好为 nil 的值的接口值不同。
  2. 持有 nil 值的接口不是 nil

解释 1 和 2 的示例:

package main

import "fmt"

func main() {
    var i1 interface{}
    fmt.Println("a == nil: ", i1 == nil)

    var i2 interface{}
    var p *int = nil
    i2 = p
    fmt.Println("b == nil: ", i2 == nil)
}
Run Code Online (Sandbox Code Playgroud)

输出

a == nil:  true
b == nil:  false
Run Code Online (Sandbox Code Playgroud)

它在幕后是如何工作的

基本上,Go 中的接口由两部分组成: adynamic type和 a dynamic value。当您将任何值分配给接口的 nil *int 时,现在它dynamic type是nil,因此接口现在是非 nil,并且与 nil 的任何比较都会导致*intfalsedynamic value

dynamic type仅当其和均为nil 时,接口才等于 nil dynamic value

在你的情况下

在与 nil 进行比较之前,您需要提取接口 x 的动态值。

参考下面的代码:

package main

import (
    "fmt"
)

func Foo(x interface{}) {
    fmt.Println("22, x == nil = ", (x).(*int) == nil)//22, x == nil =  true
}
func main() {
    var x *int = nil
    fmt.Println("11, x == nil = ", x == nil)// 11, x == nil =  true
    Foo(x)
}
Run Code Online (Sandbox Code Playgroud)

输出

11, x == nil =  true
22, x == nil =  true
Run Code Online (Sandbox Code Playgroud)