Search code examples
gopointerstype-switch

go type-switch how to deal with point to nil


like this, if msg point to null value, how to deal with it in clean code

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

the main func may be this

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

type test struct {
    c int
    d string
}

b_ptr is a pointer, but it point to nil, i want to judge it in test func if i use b_ptr in test func, eg: print a.c or a.d, it will crash.

i do it by this way. do if(), everywhere use a, but it too stupid.

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()
}

Solution

  • Generally this ought to be considered a problem with the caller, and therefore it should be the caller's job to deal with the fallout. Passing around non-nil interfaces that hold nil values is bad practice unless it's intentional/expected.

    If you can't avoid the non-nil interface with nil-pointer however, then you can use reflect to check if the underlying value is 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()
        }
    }