Swift 5.1 中的递归枚举问题
Problem with recursive enums in 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)
),您得到的是 (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())
我想说这可能是更 "idiomatic" 的版本。
我正在使用 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)
),您得到的是 (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())
我想说这可能是更 "idiomatic" 的版本。