一个函数的返回类型只能是具体的 Type
。
关键在于 Type
。任何完全由自身定义的结构体、类或协议都是纯粹的 Type
。 但是,当协议或结构体依赖于另一个通用类型占位符(如 T)时,则为部分类型。
Type
是编译器必须分配一定内存的数据结构。
因此,像这样的代码:
let a = Array<T>()
或者 let b = T
对于编译器来说不足以在编译时推断出结果。
因此,这是行不通的。
extension IntegerType {
func squared () -> IntegerType {
return self * self
}
}
在这里,IntegerType 是一个部分类型。它是一个通用协议,只有符合条件的时候我们才能知道确切的类型。类似于 Array。Array 本身不是一种类型,而是一个通用容器。只有当有人使用 Array() 或 Array()... 来创建它时,它才有一个类型。
你也遇到了相同的情况。
public protocol IntegerType : _IntegerType, RandomAccessIndexType {
然而,再次考虑,
public protocol RandomAccessIndexType : BidirectionalIndexType, Strideable, _RandomAccessAmbiguity {
@warn_unused_result
public func advancedBy(n: Self.Distance) -> Self
再说一遍,
public protocol _RandomAccessAmbiguity {
associatedtype Distance : _SignedIntegerType = Int
}
因此,由于RandomAccessIndexType具有自我要求,这意味着在某人符合它之前,Self是未知的占位符。它是部分类型。
由于IntegerType符合RandomAccessIndexType和需要Distance关联类型的_RandomAccessAmbuiguity。
因此,你也不能这样做。
let a: IntegerType = 12
再次提到IntegerType需要了解Self和Distance(关联类型)的信息。
而Int则提供了如下详细信息:
public struct Int : SignedIntegerType, Comparable, Equatable {
public typealias Distance = Int
因此,你可以这样做。
let a:Int = 10
因为它为SignedIntegerType提供了Self,而为其其他对应类型提供了Distance。
简单来说:
部分类型不能用于可以使用具体类型的地方。部分类型适用于其他泛型和对其进行约束。