swift - Swift 5.1 中的递归枚举问题

标签 swift xcode enums console lldb

我正在使用 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))

Screen

我认为最后一行代码出了问题。

这是什么意思?

最佳答案

evaluate(_:)ArithmeticExpression 的一个实例函数,即你必须上调用它ArithmeticExpression 的实例(该实例是 self 所指的)。 evaluate(_:) 的类型是 (ArithmeticExpression) -> Int

Swift 允许你调用类型的实例函数。您得到的是一个未绑定(bind)的实例函数。也就是说,一个函数还没有值绑定(bind)为其 self 值。这就是您在单独运行 ArithmeticExpression.evaluate 时所做的事情。您返回的未绑定(bind)实例函数具有以下类型:

(ArithmeticExpression) -> (ArithmetricExpression) -> Int
// ^---  the "self"        ^--- the "expression" param ^--- the final return value.

通过调用它并提供 product 作为参数 (ArithmeticExpression.evaluate(product)),您得到的是 (ArithmeticExpression) 类型的函数-> 整数。此函数是一个绑定(bind)实例函数,即 self 现在已绑定(bind)(它现在具有 product 的值),但正在等待调用再一次,将另一个 ArithmeticExpression 作为参数。

有两种方法可以解决这个问题以达到你想要的效果:

  1. 要么将其设为静态函数。静态函数不是在实例上调用的,而是直接在类型上调用的,就像您尝试做的那样:

    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))
    
  2. 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())
    

    我会说这可能是更“惯用”的版本。

关于swift - Swift 5.1 中的递归枚举问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60971778/

相关文章:

ios - swift:以编程方式创建 UILabel 固定宽度,根据文本长度垂直调整大小

ios - 已部署 + Swift 用户身份验证

json - 用结构解码未命名的JSON数组swift 4

ios - 如何扩展包含 UINavigationController 的 UIView

ios - 没有测试的 Xcode 中的代码覆盖率(用于手动运行)

ios - 推送 View Controller 不显示从 Storyboard添加的元素

xcode - @import 导致解析问题 : "could not build module"

c++ - 将枚举类型转换为整数,反之亦然

java - 非序数 INT 作为枚举

Java:创建预定义颜色的数组