【问题标题】:go type-switch how to deal with point to nilgo type-switch 如何处理指向 nil
【发布时间】:2021-11-08 17:06:24
【问题描述】:

这样,如果msg指向空值,干净代码

如何处理
func test(a SomeType) {
    switch msg := a.(type) {
    case *type1:
        dosomething1(a)
    case *type2:
        dosomething2(a)
    case *type3:
        dosomething3(a)
    default:
        do()
}

主要功能可能是这个

func main() {
    var b_ptr *stTest
    aa := interface{}(b)
    test(aa)
}

type test struct {
    c int
    d string
}

b_ptr 是一个指针,但它指向 nil,我想在 test func 中判断它 如果我在测试函数中使用 b_ptr,例如:打印 a.c 或 a.d,它会崩溃。

我就是这样做的。做if(),到处都用a,但是太笨了。

func test(a SomeType) {
    switch msg := a.(type) {
    case *type1:
        if msg == nil {
            return
        }
        dosomething1(a)
    case *type2:
        if msg == nil {
            return
        }
        dosomething2(a)
    case *type3:
        if msg == nil {
            return
        }
        dosomething3(a)
    default:
        do()
}

【问题讨论】:

  • 类型断言返回第二个返回值(类型 bool),只有当它为真时才做 switch case
  • 您可以使用case nil:,或者在开关上方使用if a == nil { return }。但是,如果您尝试处理包含类型化 nil 指针的非零接口值,那么问题出在调用者身上。传递这些值是不好的做法。
  • 您目前的方法在我看来是最干净的。这是不使用反射的最简洁的方法,我希望它会比反射更好。

标签: go pointers type-switch


【解决方案1】:

通常这应该被认为是调用者的问题,因此处理后果应该是调用者的工作。传递包含 nil 值的非 nil 接口是不好的做法,除非它是有意/预期的。

如果你无法避免使用 nil-pointer 的非 nil 接口,那么你可以使用reflect 来检查底层值是否为nil

func test(a SomeType) {
    if rv := reflect.ValueOf(a); !rv.IsValid() || rv.IsNil() {
        return
    }
    switch msg := a.(type) {
    case *type1:
        dosomething1(a)
    case *type2:
        dosomething2(a)
    case *type3:
        dosomething3(a)
    default:
        do()
    }
}

【讨论】:

  • 能不能明白我的方式也是可行的???而且我觉得reflect比if msg == nil {return}慢我的理解对吗?
  • 是的,它有效,但您的问题不是关于如何避免在每个 case 的块中这样做吗?
  • 是的,只有反射才能避免,非常感谢
猜你喜欢
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 2011-10-13
相关资源
最近更新 更多