关于array.sort的Swift - 表达式太复杂了,无法在合理的时间内解决;考虑将表达式分解为不同的子表达式

时间:2017-04-10 17:17:06

标签: swift

我正在将Swift代码从Xcode 8.3.1降级为Xcode 7.3.1。

Xcode 7.3.1的Swift编译器引发了兴趣 Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions 同时指向zeroParameterAndPaths.sort {行。 Xcode 8.3.1中的代码没问题。

有什么问题以及如何解决?

class NewConnectingSegmentZeroParameterAndPath {
    let step : Int; // 0 = main, 1 = first outline, 2 = second outline
    let parameter : CGFloat;

    init(step: Int, parameter: CGFloat) {
        self.step = step;
        self.parameter = parameter;
    }
}



var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = [];

// ... some zeroParameterAndPaths .appendContentsOf calls

zeroParameterAndPaths.sort {
            return $0.parameter < $1.parameter
                    || ($0.parameter == $1.parameter
                    && ($0.step == 1 || ($0.step == 0 && $1.step == 2))
            )
        };

3 个答案:

答案 0 :(得分:1)

你有两个选择。一个是简单地做错误信息所暗示的,即将复杂的bool拆分成单独的部分:

    zeroParameterAndPaths.sort {
        let bless = ($0.parameter < $1.parameter)
        let beq = ($0.parameter == $1.parameter)
        let band = ($0.step == 0 && $1.step == 2)
        let bor = ($0.step == 1 || band)
        let beqandbor = (beq && bor)
        return (bless || beqandbor)
    };

另一种是提供明确的in行,给出参数类型和结果类型:

    zeroParameterAndPaths.sort {
        (a:NewConnectingSegmentZeroParameterAndPath, b:NewConnectingSegmentZeroParameterAndPath) -> Bool in
        return a.parameter < b.parameter
            || (a.parameter == b.parameter
                && (a.step == 1 || (a.step == 0 && b.step == 2))
        )
    };

答案 1 :(得分:1)

您还可以让您的课程更有帮助,并使其实现条件。编译器在函数体中比在闭包中更容易混淆:

class NewConnectingSegmentZeroParameterAndPath {
    let step : Int; // 0 = main, 1 = first outline, 2 = second outline
    let parameter : CGFloat;

    init(step: Int, parameter: CGFloat) {
        self.step = step;
        self.parameter = parameter;
    }

    func orderedBefore(_ other: NewConnectingSegmentZeroParameterAndPath) -> Bool
    {
        return parameter <  other.parameter
            || parameter == other.parameter
               && (step == 1 || step == 0 && other.step == 2)
    }
}



var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = [];

// ... some zeroParameterAndPaths .appendContentsOf calls

zeroParameterAndPaths.sort { $0.orderedBefore($1) }

答案 2 :(得分:0)

除了类型推理引擎无法快速解决这种复杂的bool表达式的问题之外,这样的表达式实际上很难理解。我建议你把它分解成更简单的东西,如:

zeroParameterAndPaths.sort {
    if $0.parameter != $1.parameter { return $0.parameter < $1.parameter ]
    if $0.step == 1 { return true }
    if $0.step == 0 && $1.step == 2 { return true }
    return false
};

有我的尝试。我甚至不确定它是否正确,原始表达很难遵循。