Pet*_*Pan 3 enums func swift swift2
我正在学习 Swift 2(和 C,但也不会太久)不久,我遇到了在递归枚举方面遇到很多困难的地步。
看来,我需要把indirect在之前enum,如果它是递归的。然后我有第一个Int括号之间的情况,因为稍后在 switch 中它返回一个Integer,是吗?
现在是第二种情况的第一个问题Addition。我必须把它放在ArithmeticExpression括号之间。我试着把Int它放在那里,但它给了我一个错误,必须是一个ArithmeticExpression而不是Int. 我的问题是为什么?我无法想象那是什么。为什么我不能在Int那里放两个?
下一个问题ArithmeticExpression又来了。在func solution它进入一个名为 expression 的值中,它的类型ArithmeticExpression是 ,这是正确的吗?其余的,至少现在,完全清楚。如果有人能以简单的方式向我解释这一点,那就太好了。
这是完整的代码:
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
}
func solution(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value1):
return value1;
case . Addition(let value1, let value2):
return solution(value1)+solution(value2);
}
}
var ten = ArithmeticExpression.Number(10);
var twenty = ArithmeticExpression.Number(20);
var sum = ArithmeticExpression.Addition(ten, twenty);
var endSolution = solution(sum);
print(endSolution);
Run Code Online (Sandbox Code Playgroud)
小智 6
PeterPan,我有时认为过于现实的示例不仅会带来帮助,而且会让人困惑,因为在尝试理解示例代码时很容易陷入困境。
递归枚举只是具有关联值的枚举,这些值是枚举自身类型的情况。就是这样。只是一个枚举,其案例可以设置为与枚举相同类型的关联值。#结束
为什么这是个问题?为什么关键词是“间接”而不是“递归”?为什么需要任何关键字?
枚举“应该”按值复制,这意味着它们应该具有大小可预测的案例关联值 - 由具有基本类型(如 Integer 等)的案例组成。然后,编译器可以通过可以实例化的原始值或关联值的类型来猜测常规枚举的最大可能大小。毕竟你得到一个只选择了一个案例的枚举——所以无论案例中关联值类型的最大选项是什么,这都是枚举类型在初始化时可以获得的最大大小。然后编译器可以在堆栈上留出该数量的内存,并知道该枚举实例的任何初始化或重新分配永远不会大于该数量。如果用户将枚举设置为具有小尺寸关联值的案例,则可以,
但是,一旦您定义了一个包含具有不同大小关联类型的案例的混合的枚举,包括也是相同类型的枚举的值(因此它们本身可以使用任何枚举案例进行初始化),就不可能猜测枚举实例的最大大小。用户可以继续使用 case 进行初始化,该 case 允许与枚举类型相同的关联值 - 本身使用也是相同类型的 case 初始化,依此类推:无限递归或可能性树。指向枚举的枚举的这种递归将继续,直到使用不指向另一个枚举的“简单”类型的关联值初始化枚举。想想一个简单的 Integer 类型,它会“终止”枚举链。
因此,编译器无法在堆栈上为这种类型的枚举留出正确大小的内存块。相反,它将大小写关联值视为指向存储关联值的堆内存的指针。该枚举本身可以指向另一个枚举等等。这就是关键字是“间接”的原因——关联的值是通过指针间接引用的,而不是直接由值引用的。
它类似于将 inout 参数传递给函数——而不是编译器将值复制到函数中,而是传递一个指针来引用堆内存中的原始对象。
这就是全部。无法轻易猜测其最大大小的枚举,因为它可以使用相同类型的枚举和不可预测长度的链中不可预测的大小进行初始化。
正如各种示例所示,此类枚举的典型用途是您想要构建值树,例如在括号内具有嵌套计算的公式,或者在初始化时在一个枚举中捕获所有节点和分支的祖先树。编译器通过使用指针来引用枚举的关联值而不是堆栈上的固定内存块来处理所有这些。
所以基本上 - 如果你能想到在你的代码中你想让枚举链相互指向的情况,以及关联值的各种选项 - 那么你将使用并理解递归枚举!
Addition该案例需要两个ArithmeticExpression而不是两个的原因Int是它可以处理像这样的递归情况:
ArithmeticExpression.Addition(ArithmeticExpression.Addition(ArithmeticExpression.Number(1), ArithmeticExpression.Number(2)), ArithmeticExpression.Number(3))
Run Code Online (Sandbox Code Playgroud)
或者,在多行上:
let addition1 = ArithmeticExpression.Addition(ArithmeticExpression.Number(1), ArithmeticExpression.Number(2))
let addition2 = ArithmeticExpression.Addition(addition1, ArithmeticExpression.Number(3))
Run Code Online (Sandbox Code Playgroud)
这代表:
(1 + 2) + 3
Run Code Online (Sandbox Code Playgroud)
递归定义不仅允许您添加数字,还允许您添加其他算术表达式。这就是它的强大之处enum:它可以表达多个嵌套的加法运算。
| 归档时间: |
|
| 查看次数: |
1781 次 |
| 最近记录: |