Xcode 16 中的谓词过于复杂

问题描述 投票:0回答:1

在 Xcode 16 上,尝试编译时出现错误“编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式” (此处宏“谓词”的扩展)

相同的代码在 Xcode 15 上编译并运行良好。删除除以 || 的六个部分中的任意两个部分编译得很好。

代码:

class FeaturesPredicate {
    class func predicate(_ enabledFeaturesName: String) -> Predicate<Caliber> {
        #Predicate {
            caliber in
            caliber.caliberData.featuresABCD.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresA.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresB.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresC.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresD.contains {
               feature in
               enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresN.contains {
                feature in
                enabledFeaturesName == feature.name
            }
        }

扩展谓词:

        Foundation.Predicate({
                    caliber in
            PredicateExpressions.build_Disjunction(
                lhs: PredicateExpressions.build_Disjunction(
                    lhs: PredicateExpressions.build_Disjunction(
                        lhs: PredicateExpressions.build_Disjunction(
                            lhs: PredicateExpressions.build_Disjunction(
                                lhs: PredicateExpressions.build_contains(
                                    PredicateExpressions.build_KeyPath(
                                        root: PredicateExpressions.build_KeyPath(
                                            root: PredicateExpressions.build_Arg(caliber),
                                            keyPath: \.caliberData
                                        ),
                                        keyPath: \.featuresABCD
                                    )
                                ) {
                        feature in
                                    PredicateExpressions.build_Equal(
                                        lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                                        rhs: PredicateExpressions.build_KeyPath(
                                            root: PredicateExpressions.build_Arg(feature),
                                            keyPath: \.name
                                        )
                                    )
                                },
                                rhs: PredicateExpressions.build_contains(
                                    PredicateExpressions.build_KeyPath(
                                        root: PredicateExpressions.build_KeyPath(
                                            root: PredicateExpressions.build_Arg(caliber),
                                            keyPath: \.caliberData
                                        ),
                                        keyPath: \.featuresA
                                    )
                                ) {
                        feature in
                                    PredicateExpressions.build_Equal(
                                        lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                                        rhs: PredicateExpressions.build_KeyPath(
                                            root: PredicateExpressions.build_Arg(feature),
                                            keyPath: \.name
                                        )
                                    )
                                }
                            ),
                            rhs: PredicateExpressions.build_contains(
                                PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_KeyPath(
                                        root: PredicateExpressions.build_Arg(caliber),
                                        keyPath: \.caliberData
                                    ),
                                    keyPath: \.featuresB
                                )
                            ) {
                        feature in
                                PredicateExpressions.build_Equal(
                                    lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                                    rhs: PredicateExpressions.build_KeyPath(
                                        root: PredicateExpressions.build_Arg(feature),
                                        keyPath: \.name
                                    )
                                )
                            }
                        ),
                        rhs: PredicateExpressions.build_contains(
                            PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_Arg(caliber),
                                    keyPath: \.caliberData
                                ),
                                keyPath: \.featuresC
                            )
                        ) {
                        feature in
                            PredicateExpressions.build_Equal(
                                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                                rhs: PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_Arg(feature),
                                    keyPath: \.name
                                )
                            )
                        }
                    ),
                    rhs: PredicateExpressions.build_contains(
                        PredicateExpressions.build_KeyPath(
                            root: PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_Arg(caliber),
                                keyPath: \.caliberData
                            ),
                            keyPath: \.featuresD
                        )
                    ) {
                       feature in
                        PredicateExpressions.build_Equal(
                            lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                            rhs: PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_Arg(feature),
                                keyPath: \.name
                            )
                        )
                    }
                ),
                rhs: PredicateExpressions.build_contains(
                    PredicateExpressions.build_KeyPath(
                        root: PredicateExpressions.build_KeyPath(
                            root: PredicateExpressions.build_Arg(caliber),
                            keyPath: \.caliberData
                        ),
                        keyPath: \.featuresN
                    )
                ) {
                        feature in
                    PredicateExpressions.build_Equal(
                        lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                        rhs: PredicateExpressions.build_KeyPath(
                            root: PredicateExpressions.build_Arg(feature),
                            keyPath: \.name
                        )
                    )
                }
            )
        })
ios swift predicate swiftdata xcode16
1个回答
0
投票

正如错误消息所示,您应该将其分解为更小的部分,然后组合它们。

在这里,我将每个

contains
称为自己单独的
Predicate
,并且我还将大析取分解为两半。

class func predicate(_ enabledFeaturesName: String) -> Predicate<Caliber> {
    let featuresABCD = #Predicate<Caliber> { caliber in
        caliber.caliberData.featuresABCD.contains {
            feature in
            enabledFeaturesName == feature.name
        }
    }
    let featuresA = #Predicate<Caliber> { caliber in
        caliber.caliberData.featuresA.contains {
            feature in
            enabledFeaturesName == feature.name
        }
    }
    let featuresB = #Predicate<Caliber> { caliber in
        caliber.caliberData.featuresB.contains {
            feature in
            enabledFeaturesName == feature.name
        }
    }
    let featuresC = #Predicate<Caliber> { caliber in
        caliber.caliberData.featuresC.contains {
            feature in
            enabledFeaturesName == feature.name
        }
    }
    let featuresD = #Predicate<Caliber> { caliber in
        caliber.caliberData.featuresD.contains {
            feature in
            enabledFeaturesName == feature.name
        }
    }
    let featuresN = #Predicate<Caliber> { caliber in
        caliber.caliberData.featuresN.contains {
            feature in
            enabledFeaturesName == feature.name
        }
    }
    
    let firstHalf = #Predicate<Caliber> { caliber in
        featuresABCD.evaluate(caliber) ||
        featuresA.evaluate(caliber) ||
        featuresB.evaluate(caliber)
    }
    
    let secondHalf = #Predicate<Caliber> { caliber in
        featuresC.evaluate(caliber) ||
        featuresD.evaluate(caliber) ||
        featuresN.evaluate(caliber)
    }
    
    return #Predicate {
        caliber in
        firstHalf.evaluate(caliber) ||
        secondHalf.evaluate(caliber)
    }
}

这在我的计算机上编译得非常快。如果您只想成功编译,则不必对其进行太多分解。您可以将 firstHalf

secondHalf
组合成一个
#Predicate
,但在我的计算机上编译需要相当长的时间。
请注意,这使用 

build_evaluate

,这需要 iOS 17.4。

© www.soinside.com 2019 - 2024. All rights reserved.