我在 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/