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

在前文中我们分别讨论了类型循环依赖, 以及构建初始化顺序时初始化表达式的循环依赖问题,还有一个循环依赖问题需要考虑:Object 对象的循环依赖问题。

给定一个 Object 对象,类型检查的入口是函数check.objDecl(), 该函数的主要职责有两个:

  1. 对 Object 对象进行类型检查

  2. 检测被检查对象是否有循环依赖

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

类型检查器通过记录两个信息来做对象的循环依赖检测:

  1. 给对象标色Object 接口给对象的颜色定义了 getter 与 setter 方法(color 与 setColor),每个对象可以有三种不同的颜色: a. 白色(white):该对象还没有进行类型检查,这也是所有对象的初始颜色 b. 灰色(grey):该对象正在类型检查中 c. 黑色(black):该对象已经完成类型检查

  2. 记录对象检查的路径 对象依赖形成的结构是一个有向图(Directed Graph),类型检查会顺着依赖路径遍历所有的节点。Checker中定义了一个objPath属性,该属性用来记录当前类型检查所遍历过的所有对象,也就是当前的对象依赖路径。

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

type A struct {
	parent *A
}

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

最后更新于