我已经创建了我的自定义序列类型,我希望该函数接受任何类型的序列作为参数。 (我想同时使用这两个集合,以及我的序列类型)
像这样:
private func _addToCurrentTileset(tilesToAdd tiles: SequenceType)
有什么办法可以做到吗?
看起来比较简单,但我怎么也想不通。 Swift 工具链告诉我:
Protocol 'SequenceType' 只能用作通用约束,因为它具有 Self 或相关类型要求
,我不知道如何创建一个符合 SequenceType 和 Self 要求的协议(protocol).
我可以消除 associatedType 要求,但不能消除 Self:
protocol EnumerableTileSequence: SequenceType {
associatedtype GeneratorType = geoBingAnCore.Generator
associatedtype SubSequence: SequenceType = EnumerableTileSequence
}
现在如果说我可以消除 self 要求,那么已经有了这样的协议(protocol)定义的其他 collectionType 实体,如数组、集合将不符合它。
引用: 我的自定义序列都是枚举器类型的子类,定义为:
public class Enumerator<T> {
public func nextObject() -> T? {
RequiresConcreteImplementation()
}
}
extension Enumerator {
public var allObjects: [T] {
return Array(self)
}
}
extension Enumerator: SequenceType {
public func generate() -> Generator<T> {
return Generator(enumerator: self)
}
}
public struct Generator<T>: GeneratorType {
let enumerator: Enumerator<T>
public mutating func next() -> T? {
return enumerator.nextObject()
}
}
最佳答案
编译器会告诉您答案:“Protocol 'Sequence' 只能用作通用约束,因为它具有 Self 或相关类型要求”。 p>
因此,您可以使用泛型来做到这一点:
private func _addToCurrentTileset<T: Sequence>(tilesToAdd tiles: T) {
...
}
这将允许您将符合 Sequence
的任何具体类型传递到您的函数中。 Swift 将推断具体类型,允许您传递序列而不会丢失类型信息。
如果你想将序列中元素的类型限制为给定的协议(protocol),你可以这样做:
private func _addToCurrentTileset<T: Sequence>(tilesToAdd tiles: T) where T.Element: SomeProtocol {
...
}
或者具体类型:
private func _addToCurrentTileset<T: Sequence>(tilesToAdd tiles: T) where T.Element == SomeConcreteType {
...
}
如果您不关心序列本身的具体类型(对于将它们混合在一起以及在大多数情况下存储它们很有用),那么 Anton's answer已向您介绍 Sequence
的类型删除版本。
关于Swift:任何类型的序列作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37458665/