bre*_*top 9 xcode functional-programming compiler-errors ios swift
我正在制作一个非常简单的计算器,我得到一个非常奇怪的编译时错误.我在CalculatorBrain班上遇到以下错误:
表达太复杂,无法在合理的时间内解决; 考虑将表达式分解为不同的子表达式
这是生成错误的代码
private var operations: Dictionary<String, Operation> = [
    "?" : .Constant(M_PI),
    "±" : .UnaryOperation({ -$0 }),
    "×" : .BinaryOperation({ $0 * $1 }),
    "÷" : .BinaryOperation({ $0 / $1 }),
    "+" : .BinaryOperation({ $0 + $1 }),
    "?" : .BinaryOperation({ $0 - $1 }),
    "=" : .Equals
]
奇怪的是,如果我删除以下内容:
"±" : .UnaryOperation({ -$0 })
"+" : .BinaryOperation({ $0 + $1 })
"?" : .BinaryOperation({ $0 - $1 })
代码编译,否则会抛出错误.
另一个奇怪的事情是,如果我将其更改为:
"±" : .UnaryOperation({ (op1: Double) -> Double in return -op1 })
"+" : .BinaryOperation({ (op1: Double, op2: Double) -> Double in return op1 + op2 })
"?" : .BinaryOperation({ (op1: Double, op2: Double) -> Double in return op1 - op2 })
代码编译并不会抛出错误.
我有种困惑,为什么它使用的运营商时的工作*和/不-和+
万一你想知道如何Operation实现,这里是:
private enum Operation {
    case Constant(Double)
    case UnaryOperation((Double) -> Double)
    case BinaryOperation((Double, Double) -> Double)
    case Equals
}
我在Xcode版本7.3.1上使用Swift 2.2版
它与类型推断有关.有关更一般性的讨论,请参阅此答案.
在您的特定情况下,正是闭包中发生的类型推断导致编译器出现问题.我相信这就是为什么当你在闭包表达式中提供特定的类型注释时,编译器能够解决问题.
我建议将闭包存储在外部常量中:
let addition: (Double, Double) -> Double = { $0 + $1 }
let subtraction: (Double, Double) -> Double = { $0 - $1 }
// etc...
然后在operations字典中使用这些常量:
private var operations: Dictionary<String, Operation> = [
    "+" : .BinaryOperation(addition),
    "?" : .BinaryOperation(subtraction)
    /// etc...
]
这将为编译器提供解决所有问题所需的内容,而且它也更清晰(我认为).
编辑:我发现这之后我意识到有一种更简洁的方式来编写闭包:
let addition: (Double, Double) -> Double = (+)
let subtraction: (Double, Double) -> Double = (-)
这更清楚(我认为).
一些其他选项将满足编译器并减少一些代码重复包括创建二进制操作数组:
let binaryOps: [((Double, Double) -> Double)] = [(+), (-), (/), (*)]
然后通过索引访问它们:
private var operations: Dictionary<String, Operation> = [
    "+" : .BinaryOperation(binaryOps[0]),
    "?" : .BinaryOperation(binaryOps[1])
    /// etc...
]
或者创建一个typealias:
typealias BinaryOp = (Double, Double) -> Double
let addition: BinaryOp = (+)
let subtraction: BinaryOp = (-)
这些减少了一些冗长,但是你这样做,我认为你将不得不在某处使用特定的类型注释来满足编译器.
| 归档时间: | 
 | 
| 查看次数: | 4195 次 | 
| 最近记录: |