# 4.4.3 数据结构 - Object 对象

`Object`定义了一个接口，用来表示程序中的各类命名实体，即前文一直提到的符号对象，例如函数、变量、类型等。编译器内部为不同的符号类型定义了不同的数据结构，所有定义都在文件 `$GCROOT/compile/internal/types2/object.go` 中。

## 4.4.3.1. 接口及公用结构

接口 `type Object interface{...}` 的声明如下：

```go
// An Object describes a named language entity such as a package,
// constant, type, variable, function (incl. methods), or label.
// All objects implement the Object interface.
// 
type Object interface {
	Parent() *Scope  // scope in which this object is declared; nil for methods and struct fields
	Pos() syntax.Pos // position of object identifier in declaration
	Pkg() *Package   // package to which this object belongs; nil for labels and objects in the Universe scope
	Name() string    // package local object name
	Type() Type      // object type
	Exported() bool  // reports whether the name starts with a capital letter
	Id() string      // object name if exported, qualified name if not exported (see func Id)

	// String returns a human-readable string of the object.
	String() string

	// order reflects a package-level object's source order: if object
	// a is before object b in the source, then a.order() < b.order().
	// order returns a value > 0 for package-level objects; it returns
	// 0 for all other objects (including objects in file scopes).
	order() uint32

	// color returns the object's color.
	color() color

	// setType sets the type of the object.
	setType(Type)

	// setOrder sets the order number of the object. It must be > 0.
	setOrder(uint32)

	// setColor sets the object's color. It must not be white.
	setColor(color color)

	// setParent sets the parent scope of the object.
	setParent(*Scope)

	// sameId reports whether obj.Id() and Id(pkg, name) are the same.
	sameId(pkg *Package, name string) bool

	// scopePos returns the start position of the scope of this Object
	scopePos() syntax.Pos

	// setScopePos sets the start position of the scope for this Object.
	setScopePos(pos syntax.Pos)
}

```

该接口申明的方法比较多，但基本都是属性的 Getter 或者 Setter 方法，公用信息定义在结构`type object struct{...}`中，具体声明如下：

```go
type object struct {
	parent    *Scope
	pos       syntax.Pos
	pkg       *Package
	name      string
	typ       Type
	order_    uint32
	color_    color
	scopePos_ syntax.Pos
}
```

object 完整地实现了`Object`接口。其中`color_`属性用于后期的[对象循环依赖检查](/golang-bian-yi-qi-lei-xing-jian-cha/4.5.32a-dui-xiang-xun-huan-yi-lai-jian-cha.md)，而`typ`属性用来保存该对象的实际类型，类型推导目的就是要为每个对象推导出该属性，[类型数据结构](/golang-bian-yi-qi-lei-xing-jian-cha/4.4.1-shu-ju-jie-gou-zuo-yong-yu.md#32-lei-xing-shu-ju-jie-gou)一节将会详细介绍各种类型的数据结构。

## 4.4.3.2. 具体Object类型

编译器一共定义了 8 类 Object, 包括：

* PagName: 包对象
* Const: 常量对象
* TypeName: 代表通过`type`关键字定义的类型，或者类型别名
* Var: 代表一个变量声明，通过用来表示函数的参数、返回值，以及结构体的 Field
* Func: 代表一个方法、函数声明，或者接口内的方法声明
* Label: 代表程序内的一个 label, 用于 break, goto 等关键字；其没有 type 属性
* Builtin: 代表一个内置函数
* Nil: 代表 nil 值
* dependency: 用来标识初始化表达式可能依赖的对象，只有`Const`, `Var`, 以及`Func`是合法的该类对象。该类对象用于构建全局变量的初始化顺序，这在后面会有详细介绍。

每种类型的自定义属性并不多，基本都只是复用了 object, 所以在这里就不一一列举代码了，详情请读者自行查阅`$GCROOT/compile/internal/types2/object.go`。

## 4.4.3.3. Object对象的等价性

每个 Object 对象都代表着程序的一个符号，所以只有指向同一个符号的两个 Object 对象才是等价的，而在不同作用域的两个符号即使在结构上完全一样，也是不同的对象，这一点与类型的等价规则不同。[类型的等价规则](/golang-bian-yi-qi-lei-xing-jian-cha/4.4.412-lei-xing-de-deng-jia-gui-ze-fl.md)会在后面详细介绍。

## 4.4.3.4. Object的作用

Object 对象是类型检查的重要数据结构，准确地说，该对象的内部封装了符号对象的各方面信息：包、作用域、类型、位置信息等；每一个 Object 都与 AST 中的一个节点（Node）对应，类型检查器保存了这两类信息的映射关系（[Checker](/golang-bian-yi-qi-lei-xing-jian-cha/4.4.5-lei-xing-jian-cha-qi.md#3-checker) 的 objMap 属性）。

类型检查的目的，就是将所有 Object 对象的类型属性，即 object 中的 typ 属性推导出来，并检查整个类型系统的兼容性。事实上，类型检查的整个逻辑都是围绕着 Object 对象展开的，我们会在[类型检查逻辑](/golang-bian-yi-qi-lei-xing-jian-cha/lei-xing-jian-cha-luo-ji.md)一节对其进行详细分析。在此之前，我们先来熟悉一下编译器内部的类型数据结构。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gocompiler.shizhz.me/golang-bian-yi-qi-lei-xing-jian-cha/4.4.3-shu-ju-jie-gou-object-dui-xiang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
