如何为NSSortDescriptor实现通用KeyPath,解决泛型参数无法推断问题
报错原因
你遇到的Generic parameter 'V' could not be inferred(泛型参数V无法被推断)问题来自两个核心点:
- 调用
FilteredList的闭包参数没有明确标注singer的类型,编译器无法先推断出泛型参数T是Singer,自然也没法继续推断keyPath对应的泛型参数V的类型 - 你的
Singer.lastName是String?可选类型,Swift 5.3及以上版本才默认支持可选类型遵循Comparable协议,低版本需要额外处理
最快修复方案
直接修改调用FilteredList的闭包部分,明确标注singer的类型即可,不需要改动FilteredList的内部代码:
FilteredList(filterKey: "lastName", filterValue: lastNameFilter, keyPath: \Singer.lastName, ascendingOrNot: true) { (singer: Singer) in // 仅增加此处的类型标注 Text("\(singer.wrappedLastName)") }
更友好的优化方案(可选)
如果不想每次调用都手动标注参数类型,可以调整FilteredList的泛型适配逻辑,兼容可选类型的Core Data属性:
struct FilteredList<T: NSManagedObject, Content: View, V: Comparable>: View { var fetchRequest: FetchRequest<T> var singers: FetchedResults<T> { fetchRequest.wrappedValue } let content: (T) -> Content // 将keyPath的类型调整为可选适配 init(filterKey: String, filterValue: String, keyPath: KeyPath<T, V?>, ascending: Bool, @ViewBuilder content: @escaping (T) -> Content) { fetchRequest = FetchRequest<T>( entity: T.entity(), sortDescriptors: [NSSortDescriptor(keyPath: keyPath, ascending: ascending)], predicate: NSPredicate(format: "%K BEGINSWITH %@", filterKey, filterValue) ) self.content = content } var body: some View { List(singers, id: \.self) { singer in content(singer) } } }
调整后调用时不需要额外标注参数类型,编译器可以自动完成所有泛型参数的推断。
内容的提问来源于stack exchange,提问作者pakobongbong
相关产品推荐
相关产品推荐

