【发布时间】:2014-08-15 06:57:34
【问题描述】:
有没有办法将扩展应用于泛型类型以使其符合协议,而该扩展仅对泛型类型的某些特化有效?
例如,考虑这个协议,它返回一个字典,计算符合协议的实例包含的值的频率:
// a type conforming to this protocol should return a dictionary
// which counts the frequencies of values contained by the type instance
protocol ConvertibleToFrequencyDictionary {
typealias ItemType
func dictionaryCountingFrequencies<ItemType:Hashable>() -> Dictionary<ItemType,Int>
}
因为被计数的值必须作为字典的键,所以这些值必须是符合 Hashable 的类型。这通过泛型dictionaryCountingFrequencies 方法定义的类型约束来表示。 (我没有看到任何直接在关联类型上定义类型约束的方法,例如,在“typealias”声明中。)
现在考虑 Array 上的这个扩展,旨在使其符合协议:
extension Array : ConvertibleToFrequencyDictionary {
typealias ItemType=Element
func dictionaryCountingFrequencies<ItemType:Hashable>() -> Dictionary<ItemType,Int> {
var valueToCount = Dictionary<ItemType,Int>()
for item in self {
if let existingCount = valueToCount[item] {
valueToCount.updateValue(value: existingCount + 1, forKey: item)
} else {
valueToCount.updateValue(value: 1, forKey: item)
}
}
return valueToCount;
}
}
这应该返回出现在数组中的每个不同值的频率。但当然,由于这些值必须是可散列的,因此该扩展仅在应用于 Array<T:Hashable> 时才有效。
但这不适用于Array<Int>,即使 Int 是可散列的。
为什么不呢?如果您在泛型类型上编写扩展,该扩展是否必须能够适用于泛型类型的所有可能特化?
【问题讨论】: