enum Tree{
case Leaf(String)
case Node(Tree)
} //compiler not happy!!
enum Tree{
case Leaf(String)
case Node([Tree])
} //compiler is happy in (arguably) a more complex recursive scenario?
Swift编译器如何处理第二个(更复杂的)场景而不是第一个?
答案 0 :(得分:10)
值得注意的是Swift 2 beta 2并且还具有递归枚举的indirect
关键字 - 这意味着
enum Tree<T> {
case Leaf(T)
indirect case Node(Tree)
}
是有效的语言构造,在Swift 2中不会破坏模式匹配。
TL;决定的DR:&#34; [...]我们认为正确的解决方案是不通过枚举来支持一般的,非显而易见的递归,并要求程序员用间接的方式明确地调解它。&# 34;
答案 1 :(得分:3)
值类型(枚举)不能将自身包含为直接成员,因为无论数据结构有多大,它都不能包含自身。枚举案例的显然关联数据被认为是枚举的直接成员,因此关联数据不能是枚举本身的类型。 (实际上,我希望它们能够使递归枚举工作;对于功能数据结构来说它会非常棒。)
但是,如果你有一个间接级别,那就没关系。例如,关联数据可以是对象(类的实例),该类可以具有枚举的成员。由于类类型是引用类型,它只是一个指针而不直接包含对象(因而也就是枚举),所以它很好。
您的问题的答案是:[Tree]
不直接包含Tree
成员。 Array
的字段是私有的,但我们通常可以推断出数组元素的存储没有直接存储在Array
结构中,因为这个结构对于给定的{{{{{}}具有固定的大小。 1}},但数组可以有无限数量的元素。
答案 2 :(得分:1)
3 *}
Apple开发者论坛上的Chris Lattner(Swift设计师)says已经成为一种在参考文献中“封装”表达值的方法(例如 解决递归枚举的限制。)
但是,以下代码(适用于Swift 1.1)在Xcode Beta版本6.3(6D520o)附带的Swift 1.2中不起作用。错误消息是“属性只能应用于声明,而不是类型”,但是如果这是预期的,我不知道如何将它与Lattner关于他在前面引用中谈到的行为的声明进行协调是“有用的”事情,我们还没有用Swift 1.2删除它。“
enum BinaryTree {
case Leaf(String)
case Node(@autoclosure () -> BinaryTree, @autoclosure () -> BinaryTree)
}
let l1 = BinaryTree.Leaf("A")
let l2 = BinaryTree.Leaf("B")
let l3 = BinaryTree.Leaf("C")
let l4 = BinaryTree.Leaf("D")
let n1 = BinaryTree.Node(l1, l2)
let n2 = BinaryTree.Node(l3, l4)
let t = BinaryTree.Node(n1, n2)