知识卡片

递归枚举与indirect装箱

专业/工作 · 748.b

内容

枚举实例的内存大小由编译器按[[关联值让枚举成为代数数据类型]]中”关联值最大的那个成员”决定——固定、可预先计算。但如果某个成员的关联值类型正是这个枚举自身(如用枚举表示家谱树,一个节点的”祖先”字段又是同一个枚举类型),编译器要计算这个枚举多大就得先知道这个枚举多大,陷入无限递归、理论上需要无限内存。Swift的解法是用indirect关键字标记枚举或具体某个递归成员,让编译器不再把关联数据直接内联存放,而是存一个指向堆上数据的指针——指针大小固定(64位系统上8字节),递归结构由此被拆成一条指针链,编译器不需要再算出”整棵树”的大小。发散:这和很多语言里”递归数据结构必须用指针/引用”的规则本质相同,只是Swift把这层选择做成了显式的关键字而非默认强制用引用类型。

参考来源

《Swift编程权威指南》第14章《枚举》