简写的闭包数组:Xcode Swift:表达式太复杂,无法在合理的时间内解决

时间:2016-10-09 17:56:20

标签: arrays swift xcode closures tuples

我正在做简单的转换(例如,英制到公制)。我已经创建了一个带有(String,Closure)元素的元组数组。这允许我为转换添加一个字符串(例如"英里到公里"进入一个选择器控件,并在一行中引用相关的公式,传递值进行转换。问题我' m当我使用$ 0闭合速记时,我得到一个错误"表达式太复杂,无法在合理的时间内解决。"

这是宣言&有效的代码:

在初始类语句下面用ViewController属性声明:

var formulaTuple = [(convString: String, convFormula: ((Double) -> Double))]()

在viewDidLoad()

中指定
    formulaTuple = [("miles to kilometers", {(a: Double) -> Double in return (a / 0.62137) }),
               ("kilometers to miles", {(a: Double) -> Double in return (a * 0.62137) }),
               ("feet to meters", {(a: Double) -> Double in return (a / 3.2808) }),
               ("yards to meters", {(a: Double) -> Double in return (a / 1.0936) }),
               ("meters to feet", {(a: Double) -> Double in return (a * 3.2808) }),
               ("meters to yards", {(a: Double) -> Double in return (a * 1.0936) }),
               ("inches to centimeters", {(a: Double) -> Double in return (a / 0.39370) }),
               ("centimeters to inches", {(a: Double) -> Double in return (a * 0.39370) }),
               ("fahrenheit to celsius", {(a: Double) -> Double in return ((a - 32) * (5/9)) }),
               ("celsius to fahrenheit", {(a: Double) -> Double in return (a * (9/5) + 32) }),
               ("quarts to liters", {(a: Double) -> Double in return (a / 1.05669) }),
               ("liters to quarts", {(a: Double) -> Double in return (a * 1.05669) }) ]

在代码中进行调用,其中row是被单击的picker中的行,inputValue是传递给要转换的内容,outputValue是转换的结果。

outputValue = formulaTuple [row] .convFormula(inputValue)

当我尝试使用viewDidLoad()中的语法而不是上面的synatax来减少声明时出现问题:

    formulaTuple = [("miles to kilometers", {$0 / 0.62137 }),
                    ("kilometers to miles", {$0 * 0.62137 }),
                    ("feet to meters", {$0 / 3.2808 }),
                    ("yards to meters", {$0 / 1.0936 }),
                    ("meters to feet", {$0 * 3.2808 }),
                    ("meters to yards", {$0 * 1.0936 }),
                    ("inches to centimeters", {$0 / 0.39370}),
                    ("centimeters to inches", {$0 * 0.39370 }),
                    ("fahrenheit to celsius", {($0 - 32) * (5/9) }),
                    ("celsius to fahrenheit", {$0 * (9/5) + 32 }),
                    ("quarts to liters", {$0 / 1.05669 }),
                    ("liters to quarts", {$0 * 1.05669 }) ]

我认为这会更顺畅,但它似乎打破了Xcode。思考?我的方法是否根本不健全,建议采用不同的方法? 谢谢!

1 个答案:

答案 0 :(得分:2)

当你给它大数组文字然后期望它解释这个类型时,Swift并不好。在您的情况下,我希望这可以工作,因为您的formulaTuple属性已经建立了类型。

作为解决方法,您可以先初始化一个常量数组,然后将其分配给您的属性:

let temp: [(String, (Double) -> Double)] = [
            ("miles to kilometers", {$0 / 0.62137 }),
            ("kilometers to miles", {$0 * 0.62137 }),
            ("feet to meters", {$0 / 3.2808 }),
            ("yards to meters", {$0 / 1.0936 }),
            ("meters to feet", {$0 * 3.2808 }),
            ("meters to yards", {$0 * 1.0936 }),
            ("inches to centimeters", {$0 / 0.39370}),
            ("centimeters to inches", {$0 * 0.39370 }),
            ("fahrenheit to celsius", {($0 - 32) * (5/9) }),
            ("celsius to fahrenheit", {$0 * (9/5) + 32 }),
            ("quarts to liters", {$0 / 1.05669 }),
            ("liters to quarts", {$0 * 1.05669 })
]

formulaTuple = temp

替代答案

元组真正用于临时存储并从函数传回多个结果。您可能需要考虑使用struct作为数组值的类型:

struct Conversion {
    let string: String
    let formula: (Double) -> Double
}

var conversions = [Conversion]()

conversions = [
    Conversion(string: "miles to kilometers", formula: {$0 / 0.62137 }),
    Conversion(string: "kilometers to miles", formula: {$0 * 0.62137 }),
    Conversion(string: "feet to meters", formula: {$0 / 3.2808 }),
    Conversion(string: "yards to meters", formula: {$0 / 1.0936 }),
    Conversion(string: "meters to feet", formula: {$0 * 3.2808 }),
    Conversion(string: "meters to yards", formula: {$0 * 1.0936 }),
    Conversion(string: "inches to centimeters", formula: {$0 / 0.39370}),
    Conversion(string: "centimeters to inches", formula: {$0 * 0.39370 }),
    Conversion(string: "fahrenheit to celsius", formula: {($0 - 32) * (5/9) }),
    Conversion(string: "celsius to fahrenheit", formula: {$0 * (9/5) + 32 }),
    Conversion(string: "quarts to liters", formula: {$0 / 1.05669 }),
    Conversion(string: "liters to quarts", formula: {$0 * 1.05669 })
]

outputValue = conversions[row].formula(inputValue)

Swift对此更加满意,并且temp解决方法并不是必需的。