我在核心数据CDQI framework的(尚未发布的)Swift 3版本中有以下功能:
public func subquery<E: EntityAttribute>(
_ items: E,
_ query: (E) -> NSPredicate
) -> ExpressionConvertible
where E: ExpressionConvertible
当我使用这种方法时,我希望Swift的类型推断能够根据第一个参数找出E
的确切类型,所以我可以这样说:
subquery(department.employees) {
some($0.lastName.cdqiBeginsWith("S", .caseInsensitive)
}
我希望$0
成为EmployeeAttribute
的实例,这是employees
实例的department
属性的类型。但它不是。斯威夫特告诉我它只是EntityAttribute
,是EmployeeAttribute
的超类型。为了使它工作,我必须做以下事情:
subquery(department.employees) { (employee: EmployeeAttribute) in
some(employee.lastName.cdqiBeginsWith("S", .caseInsensitive)
}
这使得subquery
函数更加冗长且不太有用。
我在这里做错了什么?有没有办法让这项工作无需在封闭中提供类型证据? (请注意,我有兴趣将此作为函数和不方法。会有相应的方法,但我需要先使函数工作。)
答案 0 :(得分:1)
我无法重现这个问题。这是您正在做的事情的高度简化的骨架:
class A {}
class B:A {}
func f<T:A>(thing:T, _ closure: (T)->Void) {}
现在我们调用它并查看编译器告诉我们的推断类型:
f(thing:B()) {
let what = $0 // compiler says `what` is a B
}
因此,我必须得出结论,在您的问题中,您并未完全代表您自己的代码中发生的事情。