在 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
)
)
}
)
})
正如错误消息所示,您应该将其分解为更小的部分,然后组合它们。
在这里,我将每个
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
,但在我的计算机上编译需要相当长的时间。请注意,这使用 ,这需要 iOS 17.4。