尝试编写复杂的谓词时出现编译器错误

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

我知道那里有类似的问题,例如这个问题Combining Predicate in SwiftData但所有这些对我来说看起来不必要的复杂,我发现很难相信没有更简单的方法。

这就是我需要的:

let aPred = #Predicate<Event> {
            $0.dateStart != nil &&
            ($0.dateStart >= startOfDay && $0.dateStart <= endOfDay) ||
            ($0.dateEnd >= startOfDay && $0.dateEnd <= endOfDay) ||
            ($0.dateStart < startOfDay && $0.dateEnd >= startOfDay)
}

Event
是一个SwiftData模型,它有2个可选的日期属性
dateStart
dateEnd
,我需要将它们与2个日期
startOfDay
endOfDay

进行比较

你可能知道这会产生编译错误:

编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式。

在 Core Data 中,我们可以使用单个 NSPredicate 轻松完成此操作,如下所示:

let nsPred = NSPredicate(format: "dateStart != nil && (dateStart >= %@ && dateStart <= %@) || (dateEnd >= %@ && dateEnd <= %@) || (dateStart < %@ && dateEnd >= %@)",
                                argumentArray: [startOfDay, endOfDay,
                                                startOfDay, endOfDay,
                                                startOfDay, startOfDay])

或者如果需要,我们可以将其分解为更小的谓词,然后将

NSCompoundPredicate
.and or .or

一起使用

应该有一种简单的方法可以在 SwiftData 中实现相同的目的,而无需所有那些复杂的宏、查询和谓词表达式。

已上传最小工作项目此处。请参阅 ViewController.swift。

predicate swift-data
1个回答
0
投票

问题

这是因为您正在将

Optional<Date>
Date
进行比较。


解决方案

尝试让你的模型首先包含非可选,即使有默认的虚拟值:

var dateStart = Date(timeIntervalSinceReferenceDate: 0)
var dateEnd = Date(timeIntervalSinceReferenceDate: 0)

以某种方式摆脱可选性,例如强制展开:

let aPred = #Predicate<Event> {
    $0.dateStart != nil &&
    ($0.dateStart! >= startOfDay && $0.dateStart! <= endOfDay) ||
    ($0.dateEnd! >= startOfDay && $0.dateEnd! <= endOfDay) ||
    ($0.dateStart! < startOfDay && $0.dateEnd! >= startOfDay)
}
© www.soinside.com 2019 - 2024. All rights reserved.