enum
我可以轻松地在Swift中表达一个通用的递归枚举:
indirect enum Tree<T> {
case empty
case leaf(T)
case node(Tree, Tree)
}
鉴于此,我可以实例化Int
的一些示例树,例如:
let exampleTrees: [Tree<Int>] = [
.empty,
.leaf(10),
.node(.node(.leaf(1), .leaf(2)), .node(.leaf(3), .leaf(4)))
]
Tree
枚举以类似于递归函数的方式递归。 empty
和leaf
情况终止递归,而node
是递归情况。
使用递归函数时,通常有一对相互递归函数。一个愚蠢但经典的说明性示例是:
func isEven(_ x: Int) -> Bool {
return x == 0 ? true : isOdd(x-1)
}
func isOdd(_ x: Int) -> Bool {
return x == 0 ? false : isEven(x-1)
}
类似地,也可以声明一对相互递归的enum
:
indirect enum AB {
case a
case b(CD)
}
indirect enum CD {
case c
case d(AB)
}
鉴于这些,我可以开始创建递归值。这里有一些例子……
let exampleRecursives: [AB] = [
.a,
.b(.c),
.b(.d(.a)),
.b(.d(.b(.c)))
]
(这些显然完全是愚蠢且无用的-只是为了说明发生了什么!)
enum
AB
和CD
的定义是限制性的,因为它们不是通用的,我希望它们是通用的:
indirect enum AB<T> {
case a
case b(T)
}
indirect enum CD<T> {
case c
case d(T)
}
鉴于我有这些通用的替代方案,我希望能够表达与非通用原件相同的相互递归嵌套。我需要迅速告诉我们类型为AB<CD<AB<CD<AB<CD<AB<CD<AB<CD< …
,但是可以无限长。
我试图表达如下:
typealias RecursiveABCD = AB<CD<RecursiveABCD>>
这会给出编译错误"Circular reference"
。
我也尝试过:
typealias RecursiveAB = AB<RecursiveCD>
typealias RecursiveCD = CD<RecursiveAB>
但是同样,编译器错误"Circular reference"
。
一种解决方法是定义一种包装器,如下所示:
struct W {
init(_ x: AB<CD<W>>) {
self.x = x
}
let x: AB<CD<W>>
}
如果这样做,我可以创建示例,如下所示:
let exampleRecursives: [W] = [
W(.a),
W(.b(.c)),
W(.b(.d(W(.a)))),
W(.b(.d(W(.b(.c)))))
]
使用起来似乎很麻烦和笨拙。
是否可以在不引入包装器的情况下使用递归泛型枚举?