【问题标题】:Swift Array of FunctionsSwift 函数数组
【发布时间】:2015-02-19 18:05:31
【问题描述】:

我对 Swift 很陌生,但是通过关注Stanford iTunes U course 慢慢学习。我有一个关于在数组中存储和调用函数的问题。

我拥有的代码(如下)似乎正确地存储了函数,但是当我尝试调用其中一个函数时出现此错误:'(IntegerLiteralConvertible, IntegerLiteralConvertible) -> $T6' is not identical to (String, Op)

我发现 this answer 有助于我到达现在的位置,但现在我被困住了。

enum Op {
    case binary((Double, Double) -> Double)
}

var ops = [String: Op]()

func addOperation(symbol: String, op: Op) {
    ops[symbol] = op
}

addOperation("×", Op.binary(*))
addOperation("÷", Op.binary({ $1 / $0 }))
addOperation("+", Op.binary(+))
addOperation("−", Op.binary({ $1 - $0 }))

var newValue = ops["÷"](6, 3) // Produces the error

我的理解是ops["÷"]应该是我之前存储在数组中的函数。我没有正确调用它吗?

【问题讨论】:

    标签: swift


    【解决方案1】:

    @Nate Cook 的回答是正确的,但为什么在这种情况下必须使用枚举?考虑使用如下类型别名:

    var ops = [String: Op]()
    
        func addOperation(symbol: String, op:Op) {
            ops[symbol] = op
        }
    
        addOperation("×", (*))
        addOperation("÷", ({ $1 / $0 }))
        addOperation("+", (+))
        addOperation("−", ({ $1 - $0 }))
    
        var newValue = ops["÷"]?(3,6)
    
    // you have to put this outside of any class
    public typealias Op = (Double, Double) -> Double
    

    【讨论】:

    • 对不起,没有看到你的帖子进来!好主意;)
    • 使用枚举有什么好处吗?
    • @Phil 枚举为一组相关值定义了一个通用类型,并使您能够在代码中以类型安全的方式使用这些值。在您的情况下,枚举仅保留一个值,这就是您应该考虑使用 typealias 的原因
    【解决方案2】:

    你有两个问题。首先,下标字典返回一个可选值,所以ops["÷"] 是一个Op?,需要先解包才能使用它。

    其次,不能直接访问enum 的关联值——您只能在switch 语句中进行模式匹配时获取该值。我建议将计算属性添加到 Op 为您工作:

    enum Op {
        case binary((Double, Double) -> Double)
    
        var binaryCall: ((Double, Double) -> Double)? {
            switch self {
            case let .binary(operation):
                return operation
            }
        }
    }
    

    那么你可以这样称呼它:

    var newValue = ops["÷"]?.binaryCall?(6, 3)
    // Optional(0.5)
    

    另一种实现方法是只构建一个二进制操作字典,就像这样(你仍然需要解包一次):

    typealias BinaryOp = (Double, Double) -> Double
    
    var binaryOps: [String: BinaryOp] = [:]
    
    binaryOps["×"] = { $0 * $1 }
    binaryOps["÷"] = { $1 / $0 }
    
    newValue = binaryOps["÷"]?(6, 3)
    

    【讨论】:

    • 感谢@Nate Cook 对我的错误的解释。我真的很感激。
    猜你喜欢
    • 2014-08-16
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多