CollectionType
方法都是有效的,返回集合的方法都返回一个数组。
是否可以创建一个实现map
/ forEach
类似函数但返回类型为Self
的泛型函数?
extension CollectionType {
func otherMap(block: Generator.Element -> Generator.Element) -> Self {
var copy = self
copy.forEach {
$0 = block($0) // this obviously fails since $0 is immutable
}
return copy
}
}
更新:
这可以统一吗? (func名称说变异即使它没有,我知道;)
extension Set {
func mutateCollection(block: Generator.Element -> Generator.Element) -> Set {
var copy : Set<Element> = []
for element in self {
copy.insert(block(element))
}
return copy
}
}
extension Dictionary {
func mutateCollection(block: Generator.Element -> Generator.Element) -> Dictionary {
var copy : [Key:Value] = [:]
for keyValuePair in self {
let key = keyValuePair.0
let value = keyValuePair.1
let blockResult = block(key, value)
copy[blockResult.0] = blockResult.1
}
return copy
}
}
extension Array {
func mutateCollection(block: Generator.Element -> Generator.Element) -> Array {
var copy : [Element] = []
for element in self {
copy.append(block(element))
}
return copy
}
}
答案 0 :(得分:1)
没有承诺可以实例化或复制任意CollectionType
。所以没有办法实现你的扩展。看到这种情况的好方法是尝试为FlattenCollection
或LazyCollection
实施此功能。或者尝试创建RandomValueCollection
,然后尝试实现此方法。
但是你可以在RangeReplaceableCollectionType
上自由地做到这一点,这会做出你需要的所有承诺:
extension RangeReplaceableCollectionType {
func otherMap(block: Generator.Element -> Generator.Element) -> Self {
var copy = Self.dynamicType.init()
self.forEach {
copy.append(block($0))
}
return copy
}
}
并非所有馆藏都符合RangeReplaceableCollectionType
。可能有一个很好的理由Set
没有,所以你可能需要创建一个更简单的协议。
请记住,CollectionType
可能代表一些无意义或无法安全复制的静态内容。例如,我可能会创建一个代表“此磁盘上的文件”的CollectionType
。复制它可能会使不变量无效(例如有关缓存和文件指针的假设)。没有承诺CollectionType
是值类型。可以免费参考。