在Swift中尝试使用curring之后,我想到了下面的代码。我想看看是否有可能简化此枚举Operate
。目前,我需要这样初始化:
let multiply = Operate.Multiply.op
我希望每种情况都具有一个相关联的值,该值可以直接返回一个闭包,而不必执行此switch
块。这可能吗?
以下是您可以在Swift游乐场中运行的一些代码:
import Foundation
enum Operate {
case Plus
case Minus
case Multiply
case unsafeDivide
var op: (Double) -> (Double) -> Double {
get {
switch self {
case .Plus:
return { n in
return { n + $0}
}
case .Minus:
return { n in
return { n - $0}
}
case .Multiply:
return { n in
return { n * $0}
}
case .unsafeDivide:
return { n in
return { n / $0 }
}
}
}
}
}
let multiply = Operate.Multiply.op
let plus = Operate.Plus.op
let unsafeDivide = Operate.unsafeDivide.op
// 3 + (16 * 2) -> 35
plus(3)(multiply(16)(2))
奖金:我如何以“迅速”的方式处理unsafeDivide
的错误,也就是说,要避免这种情况:
let unsafeDivide = Operate.unsafeDivide.op
unsafeDivide(2)(0)
答案 0 :(得分:2)
您似乎正在做的是currying。您可以通过提取curry
函数来删除很多重复的代码:
func curry<A,B,C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
return { a in { b in f(a, b) } }
}
// ...
var op: (Double) -> (Double) -> Double {
switch self {
case .plus: // please follow Swift naming conventions, enum cases start with a lowercase
return curry(+)
case .minus:
return curry(-)
case .multiply:
return curry(*)
case .unsafeDivide:
return curry(/)
}
}
这看起来好多了。您似乎不喜欢switch语句,因此使用字典的方法如下:
var op: (Double) -> (Double) -> Double {
let dict: [Operate: (Double, Double) -> Double] =
[.plus: (+), .minus: (-), .multiply: (*), .unsafeDivide: (/)]
return curry(dict[self]!)
}
事实上,您可以在Swift 5.2中使用新的callAsFunction
功能,甚至在调用方也省略op
一词:
func callAsFunction(_ a: Double) -> (Double) -> Double {
op(a)
}
这允许您执行以下操作:
Operator.multiply(2)(3)
使用关联值是的另一种方式:
enum Operate {
case plus(Double)
case minus(Double)
case multiply(Double)
case unsafeDivide(Double)
func callAsFunction(_ b: Double) -> Double {
switch self {
case .plus(let a):
return a + b
case .minus(let a):
return a - b
case .multiply(let a):
return a * b
case .unsafeDivide(let a):
return a / b
}
}
}
但是我个人不喜欢它,因为拥有关联值意味着您不能简单地使用==
来比较枚举值以及其他限制。
不可能在编译时除以0,因为您传入的值可能不是编译时常数。如果只想检查编译时间常数,则可能需要像SwiftLint这样的静态代码分析器。在运行时,无论如何,Double
0的划分都是由IEEE标准定义的。它不会崩溃或什么。