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

使用go/ast的类型断言语法,go,Go,我已经通读了下面的代码,我不知道它的语法到底是什么 d.() 在里面 如果f,ok:=d.(*ast.fundecl)平均值 有人能给我解释一下吗 package main import ( "go/ast" "go/parser" "go/token" "regexp" "github.com/posener/complete" ) func functionsInFile(path string, regexp *regexp.Regexp) (

我已经通读了下面的代码,我不知道它的语法到底是什么 d.() 在里面 如果f,ok:=d.(*ast.fundecl)平均值

有人能给我解释一下吗

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
}

正如注释所说,这是一个类型断言。Go规范中描述了类型断言:

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

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
}
所以
Decls
Decl
的一部分,它是一个接口。简言之,这意味着在编译时您不知道实际的底层类型是什么(尽管您知道它满足接口),因此您需要执行运行时类型断言来验证它是否符合您的期望

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

这意味着“如果
d
实际上是一个
fundecl
,那么做这个事情。”

正如注释所说,这是一个类型断言。Go规范中描述了类型断言:

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

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
}
所以
Decls
Decl
的一部分,它是一个接口。简言之,这意味着在编译时您不知道实际的底层类型是什么(尽管您知道它满足接口),因此您需要执行运行时类型断言来验证它是否符合您的期望

    if f, ok := d.(*ast.FuncDecl); ok {
        name := f.Name.String()
        if regexp == nil || regexp.MatchString(name) {
            tests = append(tests, name)
        }
    }
这意味着“如果
d
实际上是一个
FuncDecl
,请执行此操作”。

这是一个类型断言。它可能与类型断言重复。可能重复的