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