swift - Swift 5.1 中的递归枚举问题
问题描述
我正在使用 Swift 文档在 Swift 5.1 中学习递归枚举。
这是一个代码。
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
func evaluate(_ expression: ArithmeticExpression) -> Int {
switch expression {
case let .number(value):
return value
case let .addition(left, right):
return evaluate(left) + evaluate(right)
case let .multiplication(left, right):
return evaluate(left) * evaluate(right)
}
}
}
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
print(ArithmeticExpression.evaluate(product))
我认为最后一行代码出了点问题。
这意味着什么?
解决方案
evaluate(_:)
是 的实例函数,ArithmeticExpression
即您必须在的实例上调用它ArithmeticExpression
(该实例是self
所指的)。的类型evaluate(_:)
是(ArithmeticExpression) -> Int
。
Swift 允许您在类型上调用实例函数。你得到的是一个未绑定的实例函数。也就是说,一个没有值绑定的函数作为它的self
值。当你自己运行时,这就是你正在做的事情ArithmeticExpression.evaluate
。您返回的未绑定实例函数具有以下类型:
(ArithmeticExpression) -> (ArithmetricExpression) -> Int
// ^--- the "self" ^--- the "expression" param ^--- the final return value.
通过调用它并product
作为参数 ( ArithmeticExpression.evaluate(product)
) 提供,你得到的是一个 type 的函数(ArithmeticExpression) -> Int
。此函数是一个绑定实例函数,即self
现在已绑定(它现在具有 的值product
),但它正在等待再次调用,并以另一个ArithmeticExpression
作为参数。
有两种方法可以解决这个问题以实现您想要的:
要么使它成为一个静态函数。静态函数不会在实例上调用,而是直接在类型上调用,就像您尝试做的那样:
indirect enum ArithmeticExpression { case number(Int) case addition(ArithmeticExpression, ArithmeticExpression) case multiplication(ArithmeticExpression, ArithmeticExpression) // Make it static here static func evaluate(_ expression: ArithmeticExpression) -> Int { switch expression { case let .number(value): return value case let .addition(left, right): return evaluate(left) + evaluate(right) case let .multiplication(left, right): return evaluate(left) * evaluate(right) } } } let five = ArithmeticExpression.number(5) let four = ArithmeticExpression.number(4) let sum = ArithmeticExpression.addition(five, four) let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2)) print(ArithmeticExpression.evaluate(product))
保留
evaluate
为实例函数,但直接在您要评估的实例上调用它,而不是在类型上。由于self
将是您感兴趣的表达式,因此您不再需要该expression
参数:indirect enum ArithmeticExpression { case number(Int) case addition(ArithmeticExpression, ArithmeticExpression) case multiplication(ArithmeticExpression, ArithmeticExpression) func evaluate() -> Int { switch self { case let .number(value): return value case let .addition(left, right): return left.evaluate() + right.evaluate() case let .multiplication(left, right): return left.evaluate() * right.evaluate() } } } let five = ArithmeticExpression.number(5) let four = ArithmeticExpression.number(4) let sum = ArithmeticExpression.addition(five, four) let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2)) print(product.evaluate())
我会说这可能是更“惯用”的版本。
推荐阅读
- python - 使用 ortools 选择列表中最小的两个整数值
- api - 以“成功”状态结束的弹性搜索快照是否会丢失索引文档?
- xml - 恢复包含“<”和“>”的数据
- php - 从嵌套在 for 循环中的 if 条件返回 true 的函数
- reactjs - 在 React 中将 ByteArray 下载为 pdf /handle 错误
- angular - 使用 Angular 在 Highcharts 中显示来自 CSV 的数据
- grails - Grails distinct projection 获取不同项目的结果计数
- azure-application-insights - pageViews - 名称列(页面名称前的字母)
- jenkins-plugins - HTML 报告在 Jenkins 仪表板中不可见
- css - 使用类样式化 react-select