2017-03-22 31 views
0

有沒有更好的方法來做到這一點?我需要知道v的類型是否是內置的「錯誤」類型。我覺得應該有這樣做的更合適的方法:Go AST/Types - 如何分辨錯誤?

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}" 
} 
+0

請添加一個可運行的鏈接。例如使用https://github.com/plutov/playgo – pltvs

+0

下面是一個可運行的示例:https://play.golang.org/p/MrhlFdBN3w –

+0

我覺得這個就足夠了: return info.Types [v] .Type.String()==「錯誤」 – pltvs

回答

0

Type assertion是檢查變量的類型的慣用方式。

鑑於你處理一個AST的表情,我想嘗試檢查,如果基礎類型是一個接口,如果Error()方法實現:

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 
} 
+0

在常規代碼中,是的。但是我正在掃描源文件的AST,所以我有一個ast.Expr作爲輸入。 –

+0

我已經更新了一個代碼示例 –

0

我想我更喜歡這樣的解決方案:

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 
}