为什么错误类型上的类型开关不起作用?

The code:

type baseStruct struct {
    value int
}

type myStruct baseStruct

func checkType(value interface{}) {
    switch value.(type) {
    case myStruct:
        fmt.Printf("%v is a myStruct
", value)
    default:
        fmt.Printf("%v is something else
", value)
    }
}

func main() {
    checkType(*new(baseStruct))
    checkType(myStruct(*new(baseStruct)))
}

outputs the following:

{0} is something else
{0} is a myStruct

https://play.golang.org/p/f8GjAe_Pc2l

Same for primitive types: https://play.golang.org/p/sD320wtkAs2

And yet the code:

type myError error

func checkType(value interface{}) {
    switch value.(type) {
    case myError:
        fmt.Printf("%v is a myError
", value)
    default:
        fmt.Printf("%v is something else
", value)
    }
}

func main() {
    checkType(fmt.Errorf("TEST1"))
    checkType(myError(fmt.Errorf("TEST2")))
}

outputs the following:

TEST1 is a myError
TEST2 is a myError

https://play.golang.org/p/g6ZmSv3hDzA

Why does a type switch work on everything except an error?

using composite struct you can match error, myError or something else easily.

error and myError are exclusive within the same switch statement, but it should not be a problem.

Instantiation is slightly different myError{error:fmt.Errorf("TEST2")}.

You do not need to use a ptr *myError (ie &myError..) as error is an interface, thus it will match the method set defined on the value receiver of your type.

package main

import (
    "fmt"
)

type myError struct {
    error
}

func checkType(value interface{}) {
    switch value.(type) {
    case myError:
        fmt.Printf("%v is a myError
", value)
    // case error:
    //  fmt.Printf("%v is a %T
", value, value)
    default:
        fmt.Printf("%v is something else
", value)
    }
}

func main() {
    checkType(fmt.Errorf("TEST1"))
    checkType(myError{error:fmt.Errorf("TEST2")})
}

outputs

TEST1 is something else
TEST2 is a myError