Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类型推断在Swift 3中不起作用_Swift_Generics_Swift3_Type Inference - Fatal编程技术网

类型推断在Swift 3中不起作用

类型推断在Swift 3中不起作用,swift,generics,swift3,type-inference,Swift,Generics,Swift3,Type Inference,我的核心数据Swift 3版本(尚未发布)中有以下功能: public func subquery<E: EntityAttribute>( _ items: E, _ query: (E) -> NSPredicate ) -> ExpressionConvertible where E: ExpressionConvertible 我希望$0是EmployeeAttribute的一个实例,它是部门的员工属性的类型。但事实并非如此。斯威夫特告诉我,

我的核心数据Swift 3版本(尚未发布)中有以下功能:

public func subquery<E: EntityAttribute>(
    _ items: E, 
    _ query: (E) -> NSPredicate
) -> ExpressionConvertible 
where E: ExpressionConvertible
我希望
$0
EmployeeAttribute
的一个实例,它是
部门的
员工
属性的类型。但事实并非如此。斯威夫特告诉我,它只是
EntityAttribute
,是
EmployeeAttribute
的超类型。为了让它发挥作用,我必须做到以下几点:

subquery(department.employees) { (employee: EmployeeAttribute) in
    some(employee.lastName.cdqiBeginsWith("S", .caseInsensitive)
}
这使得
子查询
函数更加冗长,用处更小


我做错了什么?有没有一种方法可以使这项工作不必在结案时提供类型证据?(请注意,我感兴趣的是将此作为一个函数而不是一个方法来执行。将有一个相应的方法,但我需要先使函数工作。)

我无法重现该问题。以下是您正在做的工作的高度简化的框架:

class A {}
class B:A {}
func f<T:A>(thing:T, _ closure: (T)->Void) {}

因此,我不得不得出结论,在您的问题中,您并没有完全代表您自己的代码中正在发生的事情。

我下载了您项目的cdqi5分支,并在TestNumberOfDepartments中使用subquery替换子查询闭包,用
{some($0.lastName.cdqiBeginsWith(“S”)替换子查询闭包,选项:。不区分大小写))}
,没有任何问题。测试编译并运行。另外,点击
$0
显示编译器将其推断为
EmployeeAttribute
。好的,我想我可能是Xcode机器中幽灵的受害者。编译器告诉我一些大意是“EntityAttribute没有成员”
lastName
”。清理和重建没有帮助。但是我重新启动了Xcode,现在问题消失了。根据,说你不能重现问题中描述的问题不是答案。@MartinR我的答案事实上是正确的。OP也不能重现这个问题。此外,我的回答不是我不能重现这个问题,而是这些事情的发展必须超出OP在他的问题中所揭示/描述的范围。最后,我认为向OP展示如何测试类型推断实际上是非常有用的,并且是帮助他的一个极好的方法。(在项目之外的一个新的干净项目中测试骨架代码是一项非常重要的技术。)但是,如果您不喜欢它,请否决它并标记它!这是一个自由的世界。
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
}