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