我正在为Collection创建一个扩展,它返回一个SubSequence。但是,如果函数的条件无效,我希望返回一个空的SubSequence,而不是零。
如何在扩展到SubSequence中返回空的Collection
// basic example:
extension Collection {
func myFunction(condition: Bool) -> SubSequence {
guard condition else {
return *EmptySubSequence*
}
...
}
}如果我只是对一个具体类型做了一个扩展,这将是非常容易的,但是在我将扩展限制在特定类型之前,我想知道它是否可以应用于Collection本身。
我发现最好的方法是prefix(0)将返回长度为0的SubSequence。
发布于 2021-02-06 03:06:01
如果您需要初始化一个空集合,则应该扩展RangeReplaceableCollection而不是Collection。RangeReplaceableCollection需要符合它的类型来实现空的初始化器。
extension RangeReplaceableCollection {
func myFunction(condition: Bool) -> SubSequence {
guard condition else {
return .init()
}
// ...
}
}发布于 2021-02-06 18:14:24
虽然我相信利奥的回答很有帮助,但我不会在这种情况下使用它。不需要添加额外的需求,比如RangeReplaceableCollection,后者也添加了replaceSubrange需求。添加这些需求对扩展的限制超过了需要。例如,Range不是RangeReplaceableCollection。(如果您真的只打算在Array上调用它,那么我建议将其显式化,而忘记Collection。)
创建“新”子序列意味着它与原始集合无关,从而破坏了索引的意义。调用init将创建与您正在处理的集合不兼容的“类似于零”的开始索引。您无法安全地比较来自不同集合的索引,即使是相同类型的索引。
prefix(0)的建议更好,但我认为对于需要这样做的普通算法来说,锚定到开头是没有帮助的。
相反,我建议在集合的末尾设置一个子序列:self[endIndex...]。
考虑myFunction的一个算法,它处理集合的某些部分,可能跳过某个部分,并返回第一个“重要”部分(即跳过空白的标记器的第一阶段)。endIndex自然会告诉你它看的最后一个地方,并允许你在那个时候开始下一个搜索。从该集合返回空子序列意味着索引始终是兼容的。您始终可以安全地设置startSearchingFrom = result.endIndex,即使它是空的。
在大多数情况下,正确的指数并不重要。但是在大多数情况下,您可能只是想在Array上使用它,而且它不需要是泛型的。如果您要使其泛化,IMO您应该确保保持您正在处理的类型的所有语义,这意味着得到正确的索引。
https://stackoverflow.com/questions/66073174
复制相似问题