【问题标题】:Strange behaviour for recursive enum in Swift (Beta 7)Swift 中递归枚举的奇怪行为(Beta 7)
【发布时间】:2014-09-03 20:58:49
【问题描述】:
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 编译器如何在第二个(更复杂的)场景而不是第一个场景下工作?

【问题讨论】:

  • 因为有一个中间步骤Array,可以避免直接递归。

标签: swift


【解决方案1】:

值得注意的是,Swift 2 beta 2 和进一步有 indirect 关键字用于递归枚举 - 这意味着

enum Tree<T> {
    case Leaf(T)
    indirect case Node(Tree)
}

是有效的语言结构,不会破坏 Swift 2 中的模式匹配。

TL;该决定的 DR:“[...] 我们认为正确的解决方案是不支持通过枚举的一般、非显而易见的递归,并要求程序员通过间接显式调解。”


【讨论】:

  • 感谢您的更新。它在那里很好,但它并不漂亮!也不知道为什么它需要从语法 pov 那里 - 解析器/编译器可以很容易地找出你的意图。
  • @Sam: Here 的原因。 tl;dr:“[...] 我们决定正确的解决方案是不支持通过枚举进行的一般、非显而易见的递归,并要求程序员通过间接显式调解。”
  • 如果@Regexident 不介意,请在答案中添加推理。
  • @mpolednik:当然,继续。 ;)
【解决方案2】:

值类型(枚举)不能作为直接成员包含自己,因为无论数据结构有多大,它都不能包含自己。显然枚举案例的关联数据被认为是枚举的直接成员,因此关联数据不能是枚举本身的类型。 (实际上,我希望他们能让递归枚举工作;这对于函数式数据结构来说非常棒。)

但是,如果您有一定程度的间接性,那也没关系。例如,关联数据可以是一个对象(类的实例),并且该类可以有一个成员,即枚举。由于类类型是引用类型,它只是一个指针,不直接包含对象(因此也包含枚举),所以没问题。

您的问题的答案是:[Tree] 不包含Tree 直接作为成员。 Array 的字段是私有的,但我们一般可以推断出数组元素的存储并不直接存储在Array 结构中,因为这个结构对于给定的Array&lt;T&gt; 具有固定大小,但是数组可以有无限数量的元素。

【讨论】:

    【解决方案3】:

    Chris Lattner(Swift 的设计师)says 在 Apple 开发者论坛上autoclosure

    已经成为一种在引用中“装箱”表达式值的方式(例如 解决递归枚举的限制)。

    但是,以下代码(适用于 Swift 1.1)在 Xcode Beta 版本 6.3 (6D520o) 附带的 Swift 1.2 中不起作用。错误消息是“属性只能应用于声明,而不是类型”,但是如果这是有意的,我不知道如何将其与拉特纳关于他在前面引用中谈到的行为的陈述相协调,即“有用东西,我们还没有在 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-15
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多