【发布时间】:2017-02-23 17:31:10
【问题描述】:
谁能解释一下为什么这个例子中的最后一个情况是编译错误?
class A{}
class B: A{}
protocol Finder{
func find< T: A>(_ f: (T)->Bool) -> T?
}
class FinderImpl : Finder{
func find<T : A>(_ f: (T) -> Bool) -> T? {
//In the real code I use T to find the instance. I.e. CoreData
return nil
}
}
let finder = FinderImpl()
//OK
let optionalB : B? = finder.find{_ in true}
let a : A = finder.find{_ in true}!
let b : B = finder.find{(b: B) in true}!
//Compile Error
let b2 : B = finder.find{_ in true}!
let a. 编译器使用(A) -> Bool. 作为闭包类型。那么返回类型就是A。
let b. 因为闭包有明确的信息,所以可以编译:(B)->Bool
let optionalB. 我想知道为什么这种情况有效,这里的闭包也没有任何信息。区别在于! operator
错误:在最后一种情况下,编译器无法推断传递给 func find 的闭包类型。它建议我投射as! B,因为它认为闭包类型是(A)->Bool。它没有使用b2 B的引用类型。
重要提示:我无法转换 as! B,因为我需要 find 函数才能实际使用类型 B。如果我转换 as! B,该函数将使用类型 A 并获取错误的实例。代码会编译,但结果会出错。
如果我删除T:A 限制,则不会出现编译错误。
对我来说,这看起来像是一个编译器错误。我认为编译器应该使用 b2 的类型来知道闭包是(B)->Bool 然后是 find 的结果类型。 T:A 限制和闭包中缺少类型信息导致它失败。
我在这里遗漏了什么吗?有什么想法吗?
【问题讨论】:
标签: swift generics compiler-errors