我能够使用 选择某一行项onTapGesture
,如果再次点击则取消选择。
问题是为什么下面的代码可以运行,而最后显示的代码却不运行?
@Binding var selectedRow: RowItem?
var body: some View {
ForEach(modelData.rows) { row in
LazyVGrid(columns: columns) {
Text("text")
Text("text")
}
.onTapGesture {
if (selectedRow?.id == row.id) {
selectedRow = nil
} else {
selectedRow = row
}
}
}
}
其中modelData.rows
是[RowItem]
,且 RowItem 是:struct RowItem: Identifiable
并且具有定义的相等函数:
static func == (lhs: RowItem, rhs: RowItem) -> Bool {
rhs.id == lhs.id
}
为什么必须id
使用,而下面的却不起作用?
.onTapGesture {
if (selectedRow? == row) {
selectedRow = nil
} else {
selectedRow = row
}
}
(失败原因:)
编译器无法在合理的时间内对此表达式进行类型检查;请尝试将表达式分解为不同的子表达式
当缺少括号、出现拼写错误、尝试访问不存在的属性或出现大多数编译器能够轻松发现的其他一些小错误时,您经常会看到“编译器无法在合理的时间内对此表达式进行类型检查”错误。但 Xcode 却不是这样。
当我使用 Xcode 16.1 尝试解决您的失败案例时,该错误实际上更有帮助:
这种混淆是因为相等函数是不必要的。因此,您可以先删除相等函数。然后错误变为:
通过专门声明 RowItem 符合 Equatable 可以解决此问题:
然后错误变为:
因此,最终的修复方法是删除
?
。在 Swift 中,您可以将可选项与非可选项进行比较,如果可选项实际上不为 nil,则会自动解包。顺便说一句,在 Swift 中,您也不需要用括号将表达式括起来: