CollectionType扩展,返回Type Self而不是Array

时间:2015-12-09 14:47:38

标签: swift generics

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
    }
}

1 个答案:

答案 0 :(得分:1)

没有承诺可以实例化或复制任意CollectionType。所以没有办法实现你的扩展。看到这种情况的好方法是尝试为FlattenCollectionLazyCollection实施此功能。或者尝试创建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是值类型。可以免费参考。