当前位置: 首页 > 面试题库 >

如何解析方法声明?

洪雨石
2023-03-14
问题内容

我正在尝试解析方法声明。基本上,我需要获取接收方基本类型(type hello)和返回类型(notypeerror)的语法节点。该ast程序包看起来很简单,但是由于某种原因,我没有获得所需的数据(即,字段为nil)。

唯一有用的数据似乎仅在Object -> Decl类型为字段的字段中提供,interface{} 因此我认为我无法序列化它。

任何帮助,将不胜感激。代码如下:

package main

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

func main() {
    // src is the input for which we want to inspect the AST.
    src := `
package mypack
// type hello is a cool type
type hello string

// type notype is not that cool
type notype int

// func printme is like nothing else.
func (x *hello)printme(s string)(notype, error){
    return 0, nil
}
`
    // Create the AST by parsing src.
    fset := token.NewFileSet() // positions are relative to fset
    f, err := parser.ParseFile(fset, "src.go", src, 0)
    if err != nil {
        panic(err)
    }

    // Inspect the AST and find our function
    var mf ast.FuncDecl
    ast.Inspect(f, func(n ast.Node) bool {
        switch x := n.(type) {
        case *ast.FuncDecl:
            mf = *x
        }
        return true
    })

    if mf.Recv != nil {
        fmt.Printf("\n receivers:")
        for _, v := range mf.Recv.List {
            fmt.Printf(",tag %v", v.Tag)
            for _, xv := range v.Names {
                fmt.Printf("name %v, decl %v, data %v, type %v",
                    xv.Name, xv.Obj.Decl, xv.Obj.Data, xv.Obj.Type)
            }
        }
    }
}

操场


问题答案:

要获取类型,您需要查看Type可能是an ast.StarExpr或an 的属性ast.Ident

这里看看这个:

package main

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

func main() {
    // src is the input for which we want to inspect the AST.
    src := `
package mypack
// type hello is a cool type
type hello string

// type notype is not that cool
type notype int

// printme is like nothing else.
func (x *hello)printme(s string)(notype, error){
    return 0, nil
}
`
    // Create the AST by parsing src.
    fset := token.NewFileSet() // positions are relative to fset
    f, err := parser.ParseFile(fset, "src.go", src, 0)
    if err != nil {
        panic(err)
    }

    // Inspect the AST and find our function
    var mf ast.FuncDecl
    ast.Inspect(f, func(n ast.Node) bool {
        switch x := n.(type) {
        case *ast.FuncDecl:
            mf = *x
        }
        return true
    })

    if mf.Recv != nil {
        for _, v := range mf.Recv.List {
            fmt.Print("recv type : ")
            switch xv := v.Type.(type) {
            case *ast.StarExpr:
                if si, ok := xv.X.(*ast.Ident); ok {
                    fmt.Println(si.Name)
                }
            case *ast.Ident:
                fmt.Println(xv.Name)
            }
        }
    }
}


 类似资料:
  • 这在这个回答中出现了,并且: 在Apple LLVM 9.1.0 CLANG-902-0.39.2中,的引用第一个并打印“1”。 GCC 8.2不接受此源文本。,抱怨:“错误:以前声明为'static‘的变量重新声明为'extern'”。 C 2018 6.2.2 4规定: 由于有两个先验声明,因此以下每个“if”子句的条件为真,第一个用于第一个先验声明,第二个用于第二个先验声明: ……如果前面声

  • 我在WEB-INF内的lib文件夹和Tomcat lib中添加了许多jar,试图解决这个问题,但没有结果(commons-beanutils-1.8.1、commons-collections-3.2.1、commons-lang-2.5、commons-logging-1.1.1、ezmorph-1.0.6、java-json、javax.json-1.0、json-lib-2.4-jdk15、

  • 问题内容: 我在package中有2节课。接口类及其实现类。在具有类的文件中,出现以下错误:。 我正在使用Eclipse Helios和 删除和添加JRE的标准解决方案不起作用。我该如何解决? 编辑: 代码: Class: Class: 项目结构:ProjectName-> Java资源-> com.jax-> Class ,Class 问题答案: Java 8支持接口中的默认方法。在JDK 8中

  • 本文向大家介绍PHP类的声明与实例化及构造方法与析构方法详解,包括了PHP类的声明与实例化及构造方法与析构方法详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP类的声明与实例化及构造方法与析构方法。分享给大家供大家参考,具体如下: 有没有什么办法可以在new对象的时候,通过传参数来改变对象的属性呢?而不是千篇一律 答:可以在类中定义构造方法,即在初始化对象的时候,就会执行,并且可以

  • 我正在通过Android Studio中的一个应用程序工作,该应用程序使用学校意图传递数据。我已经创建了传递数据的对象,并启动了,但是我不断收到一个警告,说我的方法无法解析。有什么想法吗?提前谢了。

  • 正如文件所述: Android O允许您通过在res/字体/文件夹中添加字体文件来捆绑字体作为资源。 结果: 您可以使用getFont(int)方法检索字体,其中需要传递要检索的字体的资源标识符。此方法返回Typeface对象。这将对字体的第一个重量或样式变体(如果是字体系列)进行编码。然后可以使用字体。create(typeface,style)方法来检索特定样式。 注意:TextView已经为