我正在使用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))
我认为代码的最后一行出了问题。
这是什么意思?
unbound instance functionevaluate(_:)
是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)
),您得到的是类型为(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())
我会说这可能是更“惯用”的版本。