Swift函数数组

时间:2015-02-19 18:05:32

标签: swift

我对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["÷"]应该是我之前存储在数组中的函数。我没有正确称呼它吗?

2 个答案:

答案 0 :(得分:4)

@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

答案 1 :(得分:3)

那里有两个问题。首先,下载字典会返回一个可选值,因此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)