generics - 在 Swift 中实现 Set.addSequence

标签 generics swift

我在 Swift 中实现了一个使用字典键的集合。我想实现一个 addAll(sequence) 方法,该方法采用集合中元素的任何序列类型,但我收到一个没有意义的错误。这是我的代码

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 的扩展方法的语义,但该类型签名甚至无法为我编译。

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

编辑: 刚找到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)
    }
}

但是,这只是将 sequence 转换为 Array,这完全违背了 SequenceType 的目的。

最佳答案

更新:这已在 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
        }
    }
    
  • (如 https://stackoverflow.com/a/27181111/1187415 )替换 for 循环 通过 while 循环使用 next()序列生成器,然后键入注释 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
        }
    }
    
  • (来自 "Creating a Set Type in Swift" )使用 map :

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

关于generics - 在 Swift 中实现 Set.addSequence,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26918594/

相关文章:

ios - private 与 fileprivate 在 Swift 3 中声明全局变量/常量?

ios - 无法为运行 iOS 8+ (APNS) 的设备获取设备 token

ios - 将 NSManagedObject 复制到 Swift 中的临时 NSManagedObject

ios - Swift iOS - 将数据作为包含自定义模型的自定义模型添加到 Firestore

java - 为什么 StreamEx 在收集到列表时强制我将 "? extends"添加到变量类型?

java - java generic编译时错误背后的解释?

generics - 为什么构造函数中带有可选参数的类不满足 new() 泛型约束?

vb.net - 限制列表(Of T)的大小 - VB.NET

c# - 捕获 C# 2.0 中作为类型参数给出的异常类型

swift - Spritekit 添加节点不重叠