-2

Given the codes

type Int struct {
    v int
}

func typeAssert(val any) {
    switch v := val.(type) {
    case nil:
        fmt.Println("val type is nil")
    case *Int:
        fmt.Println("val type is *Int")
        if v == nil {
            fmt.Println("val after type assertion is nil?")
        }
    }
}

func main() {
    var i1 *Int
    typeAssert(i1)
}

Output:

val type is *Int
val after type assertion is nil?

What confuses me is that since the *Int is matched in switch v := val.(type), why could the v == nil be true? If the v == nil be true, the case nil could be matched, actually, it does not.

zangw
  • 43,869
  • 19
  • 177
  • 214

1 Answers1

1

Because there are two kinds of nil with an interface value:

  1. A nil interface, which would hit the first branch of your type switch. This is like var x interface{} = nil - not only is the value nil, the type is also nil.
  2. A nil value, like var x interface = (nil)(*Int). This hits the second branch, because it has a type, the type matches the type in the switch, but the value is nil. In the code, v is a *Int whose value is nil.
Adrian
  • 42,911
  • 6
  • 107
  • 99