Swift:任何类型的序列作为函数参数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift:任何类型的序列作为函数参数相关的知识,希望对你有一定的参考价值。
我创建了自定义序列类型,我希望函数接受任何类型的序列作为参数。 (我想要使用两个集合,以及我的序列类型)
像这样的东西:
private func _addToCurrentTileset(tilesToAdd tiles: SequenceType)
有什么方法可以做到吗?
这似乎相对简单,但我无法以某种方式解决它。 Swift工具链告诉我:Protocol 'SequenceType' can only be used as a generic constraint because it has Self or associated type requirements
,我不知道如何创建一个符合SequenceType和Self要求的协议。
我可以消除associatedType要求,但不能取消Self:
protocol EnumerableTileSequence: SequenceType {
associatedtype GeneratorType = geoBingAnCore.Generator
associatedtype SubSequence: SequenceType = EnumerableTileSequence
}
现在如果说我可以消除自我要求,那么已经使用这样的协议定义其他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()
}
}
编译器告诉你答案:“协议'序列'只能用作通用约束,因为它具有自我或相关的类型要求”。
因此,您可以使用泛型来执行此操作:
private func _addToCurrentTileset<T: Sequence>(tilesToAdd tiles: T) {
...
}
这将允许您将符合Sequence
的任何具体类型传入您的函数。 Swift将推断具体类型,允许您传递序列而不丢失类型信息。
如果要将序列中元素的类型限制为给定协议,可以执行以下操作:
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
。
你可以使用type-eraser AnySequence
:
类型擦除序列。
将操作转发到具有相同
Element
类型的任意底层序列,隐藏底层SequenceType
的细节。
例如。如果您需要将tile存储为内部属性或以某种方式在对象的结构中使用其具体类型,那么这就是要走的路。
如果你只需要能够使用w / o必须存储它的序列(例如只有map
),那么你可以简单地使用泛型(如@ originaluser2建议)。例如。你最终会得到类似的东西:
private func _addToCurrentTileset<S: SequenceType where S.Generator.Element == Tile>(tilesToAdd tiles: S) {
let typeErasedSequence = AnySequence(tiles) // Type == AnySequence<Tile>
let originalSequence = tiles // Type == whatever type that conforms to SequenceType and has Tile as its Generator.Element
}
以上是关于Swift:任何类型的序列作为函数参数的主要内容,如果未能解决你的问题,请参考以下文章