Is there a better way of doing this? I need to know if the type of v is the built-in "error" type. I feel like there should be a neater way of doing this:
import (
"go/ast"
"go/types"
)
func IsError(v ast.Expr, info types.Info) bool {
t := info.Types[v]
return t.Type.String() == "error" &&
t.Type.Underlying().String() == "interface{Error() string}"
}
Type assertion is the idiomatic way of checking the type of a variable.
Given you're handling an AST expression, I'd try to check if the underlying type is an interface and if the Error()
method is implemented:
isError := func(v ast.Expr, info *types.Info) bool {
if intf, ok := info.TypeOf(v).Underlying().(*types.Interface); ok {
return intf.NumMethods() == 1 && intf.Method(0).FullName() == "(error).Error"
}
return false
}
I think I prefer this solution:
https://play.golang.org/p/MA7F4Zpwqt
isError := func(v ast.Expr, info *types.Info) bool {
if n, ok := info.TypeOf(v).(*types.Named); ok {
o := n.Obj()
return o != nil && o.Pkg() == nil && o.Name() == "error"
}
return false
}