goast查询成员的成员

package main

import (
    "fmt"
    "go/ast"
    "go/parser"
    "go/token"
    "os"
    "strings"
)

func main() {
    // 读取源文件
    fset := token.NewFileSet()
    file, err := parser.ParseFile(fset, "example.go", nil, parser.ParseComments)
    if err != nil {
        fmt.Println("Error parsing file:", err)
        return
    }

    // 遍历AST节点
    ast.Inspect(file, func(n ast.Node) bool {
        switch x := n.(type) {
        case *ast.GenDecl:
            // 查找类型定义
            for _, spec := range x.Specs {
                typeSpec, ok := spec.(*ast.TypeSpec)
                if !ok {
                    break
                }

                // 查找结构体类型
                structType, ok := typeSpec.Type.(*ast.StructType)
                if !ok {
                    break
                }

                fmt.Printf("Type: %s\n", typeSpec.Name.Name)
                for _, field := range structType.Fields.List {
                    // 检查字段类型是否为结构体
                    if structType, ok := field.Type.(*ast.StructType); ok {
                        printStructFields(structType)
                    }
                }
            }
        }
        return true
    })
}

func printStructFields(structType *ast.StructType) {
    fmt.Println("  Fields:")
    for _, field := range structType.Fields.List {
        if len(field.Names) > 0 {
            fmt.Printf("    %s %s\n", field.Names[0].Name, field.Type)
        } else {
            fmt.Printf("    %s\n", field.Type)
        }
    }
}

 

在Go语言的 go/ast 包中, *ast.StarExpr 表示一个星号表达式,通常用于表示指针类型。当你遇到一个 *ast.StarExpr 节点时,你通常想要获取它所指向的底层类型。如果这个底层类型是一个结构体,你可能还想进一步解析这个结构体的成员。
以下是如何使用 go/ast 包来解析 *ast.StarExpr 的子成员的步骤:
1. 解析源代码:首先,你需要解析包含你感兴趣的代码的Go源文件。
2. 遍历AST节点:使用 ast.Inspect 函数遍历AST节点。
3. 识别 *ast.StarExpr 节点:在遍历过程中,识别出 *ast.StarExpr 节点。
4. 获取底层类型:对于 *ast.StarExpr 节点,使用 X 字段获取它所指向的类型。
5. 进一步解析类型:如果底层类型是 *ast.StructType ,即结构体类型,你可以进一步解析结构体的成员。
下面是一个示例代码,演示了如何使用 go/ast 包来解析 *ast.StarExpr 的子成员:
package main

import (
    "fmt"
    "go/ast"
    "go/parser"
    "go/token"
    "os"
    "strings"
)

func main() {
    // 读取源文件
    fset := token.NewFileSet()
    file, err := parser.ParseFile(fset, "example.go", nil, parser.ParseComments)
    if err != nil {
        fmt.Println("Error parsing file:", err)
        return
    }

    // 遍历AST节点
    ast.Inspect(file, func(n ast.Node) bool {
        starExpr, ok := n.(*ast.StarExpr)
        if !ok {
            return true
        }

        // 获取底层类型
        underlyingType := starExpr.X
        if structType, ok := underlyingType.(*ast.StructType); ok {
            // 如果底层类型是结构体,打印其字段
            fmt.Println("Struct Type Found:")
            for _, field := range structType.Fields.List {
                fmt.Printf("  Field: %s\n", field.Names)
                for _, name := range field.Names {
                    fmt.Printf("    Name: %s, Type: %s\n", name.Name, field.Type)
                }
            }
        } else {
            // 如果不是结构体,打印类型信息
            fmt.Printf("Type: %T\n", underlyingType)
        }

        return true
    })
}
在这个示例中, main 函数首先读取一个名为 example.go 的源文件。然后,使用 ast.Inspect 函数遍历AST节点,查找 *ast.StarExpr 节点。对于每个 *ast.StarExpr 节点,它检查其 X 字段是否是 *ast.StructType 。如果是,它进一步打印出结构体的字段和类型信息。
请注意,这个示例代码假设你已经有了一个名为 example.go 的源文件,并且这个文件中定义了一些使用指针的类型。你需要根据实际情况调整文件名和路径。此外,这个示例仅打印了字段的名称和类型,你可以根据需要扩展这个函数来获取更多的信息。
 

 

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leijmdas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值