3
我想解析函數調用從代碼使用go/ast
包。在Golang中進行多重界面轉換的簡明方法?
爲了做到這一點,我首先找到所有的函數調用,如:
ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.FuncDecl:
processFunction(x)
}
return true
})
,然後processFunction()看起來是這樣的:
func processFunction(e *ast.FuncDecl) {
// Save wrapper function name
f := e.Name.Name
for _, expression := range e.Body.List {
logrus.Printf("Current stmt: %#v", expression)
pkg := expression.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).X.(*ast.Ident).Name
fn := expression.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).Sel.Name
fcall := fmt.Sprintf("%s.%s", pkg, fn)
logrus.Printf("Yay. found my function call: ", fcall)
}
}
這段代碼的問題是,如果該特定在AST中找不到層次結構,程序恐慌。我知道,我們可以通過正常
x, ok := x.(type)
做接口轉換但是,如果我做這樣的每一次轉換,我的代碼將是巨大的。當然,嘗試在這裏使用它。
pkg, ok := expression.(*ast.ExprStmt).X.(*ast.CallExpr).Fun.(*ast.SelectorExpr).X.(*ast.Ident).Name
if !ok {
continue
}
錯誤:
./parser.go:41: assignment count mismatch: 2 = 1
有一個簡潔的方式做這些一系列的轉換,如果沒有找到這個層次還不能正常?
這就是那些情況下使用一個單子的時候是可行的(不是簡單地看爽):實現一個'Either'單子和你的表情會轉換成'PKG:= Either.Of(表達).Bind(GetExpStmt ).Bind(的getX).Bind(...)'。它會返回你想要的值,或者返回一個錯誤/ null /一個帶有額外數據的結構,你可以正常處理。 – zerkms