# 4.5.3-2a 对象循环依赖检查

在前文中我们分别讨论了[类型循环依赖](/golang-bian-yi-qi-lei-xing-jian-cha/4.5.31.3e-chu-li-delayed-dui-lie.md#xun-huan-yi-lai-jian-cha), 以及[构建初始化顺序](/golang-bian-yi-qi-lei-xing-jian-cha/4.5.31.4-gou-jian-chu-shi-hua-shun-xu.md)时初始化表达式的循环依赖问题，还有一个循环依赖问题需要考虑：Object 对象的循环依赖问题。

给定一个 Object 对象，类型检查的入口是函数`check.objDecl()`, 该函数的主要职责有两个：&#x20;

1. 对 Object 对象进行类型检查&#x20;
2. 检测被检查对象是否有循环依赖

在上文中我们已经详细讨论了第一个方面的内容，这里我们分析一下第二点。

类型检查器通过记录两个信息来做对象的循环依赖检测：&#x20;

1. 给对象标色[Object 接口](/golang-bian-yi-qi-lei-xing-jian-cha/4.4.3-shu-ju-jie-gou-object-dui-xiang.md#1-jie-kou-ji-gong-yong-jie-gou)给对象的颜色定义了 getter 与 setter 方法（color 与 setColor），每个对象可以有三种不同的颜色： \
   a. 白色（white）：该对象还没有进行类型检查，这也是所有对象的初始颜色 \
   b. 灰色（grey）：该对象正在类型检查中 \
   c. 黑色（black）：该对象已经完成类型检查&#x20;
2. 记录对象检查的路径 对象依赖形成的结构是一个有向图（Directed Graph），类型检查会顺着依赖路径遍历所有的节点。[Checker](/golang-bian-yi-qi-lei-xing-jian-cha/4.4.5-lei-xing-jian-cha-qi.md#3-checker)中定义了一个`objPath`属性，该属性用来记录当前类型检查所遍历过的所有对象，也就是当前的对象依赖路径。

结合这两点我们知道，在任意时刻，`checker.objPath`都保存着所有正在进行类型检查的对象，所以当`check.objDecl()`遇到一个灰色对象时，那么可以肯定我们就遇到了一个循环依赖，并且该对象已经在 objPath 上了。但并不是所有循环依赖都是错误的，例如：

```go
type A struct {
	parent *A
}
```

从 Object 层面来说，该结构体循环依赖于自己，但这种通过指针进行依赖是合法的，所以每次 objDecl 方法检测到循环依赖都会对其合法性进行校验，该方法由方法`check.cycle()`完成。我们知道：类型的合法性与变量的初始化顺序有专门的地方进行校验，所以该方法认为这两种情况合法，除此之外都是非法的。


---

# 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.5.32a-dui-xiang-xun-huan-yi-lai-jian-cha.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.
