该结构是syntax.Parse()函数的返回结果,代表着一个源文件的 AST。其中重要的是 DeclList, 其包含了该源文件中所有的声明,声明(Declaration)是 Go 源文件顶级作用域中的唯一合法结构,声明在其内部递归地包含其他结构体。
该文件中定义的各种数据结构与 Go 语言规范 中所定义的语言结构是一一对应的,在源代码中,很多数据结构的声明上面都有对应的文法。所有的数据结构可以归为如下几类:
3.3.1 声明(Declaration)
声明就是在程序里面说“我要创建一个 X, 他的名字是 Y”,其包含两件事情:一个是命名,一个是绑定。例如 Go 中的 var name string 就是一个变量声明,其在程序中取了一个名字:name, 然后将其与 string 这种类型绑定起来,翻译成前边的语言就是:我要创建一个字符串,他的名字是 name。注意 name := "Golang" 不仅包含了声明,而且包含了赋值语句(Statement),只是声明中的类型信息是隐式的。
A declaration binds a non-blank identifier to a constant, type, variable, function, label, or package. Every identifier in a program must be declared. No identifier may be declared twice in the same block, and no identifier may be declared in both the file and package block.
由此可见,声明其实就是创建程序组件并为其命名的操作,有了这些程序组件作为积木,我们才能搭建出整个程序大厦。在 Go 语言源文件中,合法的顶级声明包括:常量、类型、变量、函数、方法 以及 package, 下面都是合法的声明:
结构体 FuncDecl 可以表示函数、方法两类声明,实际上 Go 中函数与方法没有本质区别,方法与函数的区别在于方法的第一个参数默认绑定到调用的实例上,这与 Java 的 this 关键字是一样的。因为 Go 中函数是一类公民(First Class Citizen),所以我们甚至可以将方法赋值给变量,如下代码体现了方法与函数的等价性质:
An expression specifies the computation of a value by applying operators and functions to operands.
也就是说表达式代表的是一个计算,该计算过程通过将某种运算符(operator)应用到操作数(operand)、或者将函数应用到其参数上来完成。常见的运算符包括算术运算符、逻辑运算符、位运算符等,我们对使用这类运算符做“计算”的认知是很自然的,例如表达式 i + j, 运算符(Operator)是 +, 操作数(Operand)是 i 与 j. 但对于编译器而言,运算符的范围更加宽泛,例如赋值语句的右边只能是一个表达式,形如 a := b 中的 b 必须有值返回才能将其赋给 a. 例如如下代码:
// func Name Type { Body }
// func Name Type
// func Receiver Name Type { Body }
// func Receiver Name Type
type FuncDecl struct {
Pragma Pragma
Recv *Field // 如果该函数是一个方法,则表示 Receiver, 否则为 nil
Name *Name // 函数名,是一个表达式(Expr)
TParamList []*Field // 类型参数,即泛型
Type *FuncType // 函数类型,是一个表达式(Expr),其中包含函数的参数与返回值的列表
Body *BlockStmt // 函数体的语句(Statement),如果没有函数体则为空
decl // 内嵌结构体,使该结构体实现接口 Decl
}
package main
import "fmt"
type people struct {
name string
}
func (this people) greeting(friend string) {
fmt.Println("My name is ", this.name, ", How are you ", friend)
}
func main() {
f := people.greeting
p := people{"Golang"}
f(p, "Java") // 与 f.greeting("Java") 效果一样
}
language := struct {
Name string
Age int
}{
Name: "Golang",
Age: 100,
}
type BasicLit struct {
Value string // 字面量
Kind LitKind // 字面量类型,包括整数、浮点数、字符串等
Bad bool // true means the literal Value has syntax errors
expr
}
// X[Index]
type IndexExpr struct {
X Expr // 被访问的对象,通过一个表达式来表示
Index Expr // 下标,也通过一个表达式来表示
expr
}
// All declarations belonging to the same group point to the same Group node.
type Group struct {
_ int // not empty so we are guaranteed different Group instances
}