使用go/ast来解析go文件III

可能很多人想问types中的Type和Object接口有什么区别

我觉得Object可以理解为有实体的Type或者是对Type的定义,Type则是一个Object的抽象

比如type V1 struct {Name string} 和type V2 struct {Name string} V1和V2属于不同Object但它们的Underlying Type是一样的(Type不一样是因为它们是一个Named Type类型) ,不过type不能通过==来比较,必须用Identical

使用go/ast来解析go文件II

在进行go文件解析经常需要对Ident对象的类型/值进行比较

但go/ast只对单文件进行解析,并不适合用来比较类型,所以这个时候就需要用到另一个库go/types

先来看看全部代码

代码也可以通过这里下载,建议在看教程的同时运行这个demo代码

使用go/ast来解析go文件

go/ast是go的type checker 标准包之一(不是编译器的那套工具,编译器用的另外一套),它定义了抽象语法树(AST)的数据类型和操作ast节点的工具

下面我们来看看如何ast树的结构

package main

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

func main() {
	src := `
package main

// 该声明为GenDecl TOK=token.IMPORT
import "fmt"

// 该声明为GenDecl TOK=token.TYPE
type Product struct {
	Name string
}

// 该声明为GenDecl TOK=token.VAR
var product Product

// 该声明为FunDecl
func main() { //test1
	fmt.Println("Hello, World!") //test2
	a := []int{1,2,3}
	a[1],a[2] = 5,6
}
`
	fset := token.NewFileSet() // 位置是相对于节点
	// 用ParseFile把文件解析成*ast.File节点
	f, err := parser.ParseFile(fset, "", src, 0)
	if err != nil {
		panic(err)
	}

	// 打印ast节点
	ast.Print(fset, f)
}


归档 下一页