类型推断不像Swift 3那样直观

时间:2016-10-09 15:10:42

标签: swift generics swift3 type-inference

我在核心数据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函数更加冗长且不太有用。

我在这里做错了什么?有没有办法让这项工作无需在封闭中提供类型证据? (请注意,我有兴趣将此作为函数方法。会有相应的方法,但我需要先使函数工作。)

1 个答案:

答案 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
}

因此,我必须得出结论,在您的问题中,您并未完全代表您自己的代码中发生的事情。