使用go / ast的类型断言语法

时间:2019-01-12 13:50:40

标签: go

我已经看完下面的代码,但我不知道它的语法到底是什么   d。() 在  如果f,确定:= d。(* ast.FuncDecl); 表示平均值。

有人可以帮我解释一下吗?

package main

import (
    "go/ast"
    "go/parser"
    "go/token"
    "regexp"

    "github.com/posener/complete"
)

func functionsInFile(path string, regexp *regexp.Regexp) (tests []string) {
    fset := token.NewFileSet()
    f, err := parser.ParseFile(fset, path, nil, 0)
    if err != nil {
        complete.Log("Failed parsing %s: %s", path, err)
        return nil
    }
    for _, d := range f.Decls {
        if f, ok := d.(*ast.FuncDecl); ok {
            name := f.Name.String()
            if regexp == nil || regexp.MatchString(name) {
                tests = append(tests, name)
            }
        }
    }
    return
}

1 个答案:

答案 0 :(得分:2)

正如评论所说,这是一个类型断言。 Go规范中描述了类型断言:https://golang.org/ref/spec#Type_assertions

应用于您的特定代码示例,我认为它取自AST module documentation,如果您想使用Go AST,应该阅读该示例。

ParseFile返回一个ast.File,即:

type File struct {
        Doc        *CommentGroup   // associated documentation; or nil
        Package    token.Pos       // position of "package" keyword
        Name       *Ident          // package name
        Decls      []Decl          // top-level declarations; or nil
        Scope      *Scope          // package scope (this file only)
        Imports    []*ImportSpec   // imports in this file
        Unresolved []*Ident        // unresolved identifiers in this file
        Comments   []*CommentGroup // list of all comments in the source file
}

因此DeclsDecl的一部分,而<{> 1是接口。简而言之,这意味着在编译时您不知道实际的基础类型是什么(尽管您确实知道它满足接口),因此您需要执行运行时类型声明以验证它是否符合您的期望。

    if f, ok := d.(*ast.FuncDecl); ok {
        name := f.Name.String()
        if regexp == nil || regexp.MatchString(name) {
            tests = append(tests, name)
        }
    }

这表示“如果d实际上是FuncDecl,请执行此操作。”