传入的nil对象不是nil

问题描述 投票:0回答:1
package main

import "fmt"

type Person struct {
    fname   string
    lname   string
    age     int
    address string
}

func (p *Person) GetName() string {
    return p.fname + " " + p.lname
}

func (p *Person) GetAge() int {
    return p.age
}

func (p *Person) GetAddress() string {
    return p.address
}

type IPerson interface {
    GetName() string
    GetAge() int
    GetAddress() string
}

func PrintPerson(p IPerson) {
    if p == nil {
        fmt.Println("Person is nil")
        return
    }
    fmt.Println("Name: ", p.GetName())
}

type Group struct {
    person IPerson
}

func (g *Group) Print() {
    if g.person == nil {
        fmt.Println("Person is nil")
        return
    }
    fmt.Println("Name: ", g.person.GetName())
}

func NewGroup(p *Person) *Group {
    return &Group{
        person: p,
    }
}

func main() {
    m := &Person{
        fname:   "John",
        lname:   "Doe",
        age:     22,
        address: "International Seas",
    }

    g1 := NewGroup(m)
    g2 := NewGroup(nil)
    g1.Print()
    g2.Print()
}

考虑上面的代码。即使没有检查,它也会在

panic: runtime error: invalid memory address or nil pointer dereference
处抛出
fmt.Println("Name: ", g.person.GetName())

如果我对

NewGroup
进行零签入
p
并返回

&Group{
    person: nil,
}

一切正常。

这里有什么区别?为什么接口类型对于 nil 检查的行为不同?除了 NewGroup 中的 nil 检查之外,处理此问题的惯用方法是什么?

我的期望是,自打印对象输出以来,当传递 nil 对象时,nil 检查将起作用

<nil>

go interface null
1个回答
0
投票
  • 在 Go 中,只有当接口的类型和值都为 nil 时,该接口的值才为 nil。
  • 这有时会令人困惑,因为具有 nil 具体值但非 nil 类型的接口不被视为 nil。
  • 从你的代码中,我猜你只想检查接口的值是否为零,你可以这样检查:
value := reflect.ValueOf(g.person)
log.Println("value is ", value, value.IsNil())
© www.soinside.com 2019 - 2024. All rights reserved.