一尘不染

在Swift中实现Set.addSequence

swift

我已经在Swift中实现了一个使用字典键的Set。我想实现一个addAll(sequence)方法,该方法在Set中的Elements上采用任何序列类型,但是出现一个没有意义的错误。这是我的代码

struct Set<Element: Hashable> {
    var hash = [Element: Bool]()

    init(elements: [Element] = []) {
        for element in elements {
            self.hash[element] = true
        }
    }

    var array: [Element] {
        return hash.keys.array
    }

    func contains(element: Element) -> Bool {
        return hash[element] ?? false
    }

    mutating func add(element: Element) {
        hash[element] = true
    }

    mutating func add(array: [Element]) {
        for element in array {
            hash[element] = true
        }
    }

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) {
        for element in sequence { // Error here: "Cannot convert the expression's type 'S' to type 'S'
            hash[element] = true
        }
    }

    mutating func remove(element: Element) {
        hash[element] = nil
    }
}

我在XCode 6.1和6.0.1中遇到此错误。

我想遵循Array的extend方法的语义,但是该类型签名甚至不为我编译。

我做错了什么,还是应该提交雷达?

编辑
:刚刚找到https://github.com/robrix/Set/blob/master/Set/Set.swift,它具有以下实现:

public mutating func extend<S : SequenceType where S.Generator.Element == Element>(sequence: S) {
    // Note that this should just be for each in sequence; this is working around a compiler crasher.
    for each in [Element](sequence) {
        insert(each)
    }
}

但是,这只是转换sequenceArraySequenceType完全违反了目的。


阅读 204

收藏
2020-07-07

共1个答案

一尘不染

更新: 这已在Swift 1.2(Xcode 6.3 beta
3)中修复,问题中的原始代码可正确编译。(此外,不再需要定义自定义集合类型,因为Swift 1.2具有Set内置的本机类型。)


旧答案: 对我来说,这似乎是个错误,但也许有人可以解释。

可能的解决方法:

  • sequence参数SequenceOf<Element>显式转换为:

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) {
    for element in SequenceOf<Element>(sequence)  {
        hash[element] = true
    }
    

    }

  • 使用next()序列生成器将while循环替换为while循环,并使用显式注释元素element : Element

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) {
    var gen = sequence.generate()
    while let element : Element = gen.next() {
        hash[element] = true
    }
    

    }

  • (摘自“在Swift中创建集合类型”)使用map

    mutating func add<S : SequenceType where S.Generator.Element == Element>(sequence: S) {
    map(sequence) {
        self.hash[$0] = true
    }
    

    }

2020-07-07