如何在Golang中检测结构指针是否为nil?

riv*_*ver -2 null pointers compare interface go

如以下代码所示:is n := localplugin.NewPluginNet()的类型,它是由struct指针实现的接口。函数返回指向的nil指针。nlocalnet.Net*localnet.DomainSocketfunc NewPluginNet() localnet.Netn

var n localnet.Net    
n = localplugin.NewPluginNet()
fmt.Println("----> ", n)
if n == nil {
    fmt.Println("n is nil")
}else{
    fmt.Println("n is not nil : ",  n)
}
fmt.Println(reflect.TypeOf(n), reflect.TypeOf(nil), n)
Run Code Online (Sandbox Code Playgroud)

以下是上面代码的输出。

---->  <nil>
n is not nil :  <nil>
*localnet.DomainSocket <nil> <nil>
Run Code Online (Sandbox Code Playgroud)

为什么n不为nil?

==================================

var n1 *localnet.DomainSocket
n1 = nil
fmt.Println(">> ", n1)
if n1 == nil {
    fmt.Println(">>n1 is nil")
}else{
    fmt.Println(">>n1 is not nil : ",  n)
}
fmt.Println(reflect.TypeOf(n1), reflect.TypeOf(nil), n1)
Run Code Online (Sandbox Code Playgroud)

但是,这种情况是正确的:

>>  <nil>
>>n1 is nil
*localnet.DomainSocket <nil> <nil>
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 5

为什么不n nil呢?类型n是接口类型(localnet.Net),它是一(type; value)对包装器。nil即使包装nil值,接口值也可能不是。请参阅隐藏nil值,了解golang为什么会失败

要回答标题中的问题:您可以使用反射来判断非nil接口值是否包装了一个nil值(例如nil指针):

reflect.ValueOf(someValue).IsNil()
Run Code Online (Sandbox Code Playgroud)

例:

type reader struct{}

func (*reader) Read(p []byte) (int, error) { return 0, nil }

func main() {
    var r io.Reader = (*reader)(nil)

    fmt.Println(r, r == nil)
    fmt.Println(reflect.ValueOf(r).IsNil())
}
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上尝试):

<nil> false
true
Run Code Online (Sandbox Code Playgroud)