如何 return 集合扩展中的空子序列
How to return an empty SubSequence in a Collection extension
我正在创建 Collection
的扩展,return 是 SubSequence
。但是,如果函数的条件无效,我想 return 一个空的 SubSequence
而不是 nil.
如何在 Collection
的扩展中 return 空 SubSequence
?
// basic example:
extension Collection {
func myFunction(condition: Bool) -> SubSequence {
guard condition else {
return *EmptySubSequence*
}
...
}
}
如果我只是对具体类型进行扩展,这将非常容易,但在我将扩展限制为特定类型之前,我想知道它是否可以应用于 Collection
本身。
我发现的最好的是 prefix(0)
将 return 长度为 0 的 SubSequence
。
如果您需要初始化一个空集合,您应该扩展 RangeReplaceableCollection
而不是 Collection
。 RangeReplaceableCollection
要求符合它的类型实现空初始化器。
extension RangeReplaceableCollection {
func myFunction(condition: Bool) -> SubSequence {
guard condition else {
return .init()
}
// ...
}
}
虽然我相信 Leo 的回答很有帮助,但我不会在这种情况下使用它。不需要增加RangeReplaceableCollection这样的额外需求,它也增加了replaceSubrange
的需求。添加这些要求会限制扩展超出需要。例如,Range 不是 RangeReplaceableCollection。 (如果你真的只打算在 Array 上调用它,那么我建议明确说明并忘记 Collection。)
创建一个“新的”子序列意味着它变得与原始集合无关,并且破坏了索引的含义。调用 init
将创建具有“类似零”起始索引的内容,该索引可能与您正在处理的集合不兼容。您无法安全地比较来自不同集合的索引,即使是相同类型的索引也是如此。
Sweeper 的建议 prefix(0)
更好,但我认为锚定到开头对于需要它的常见算法没有帮助。
相反,我建议在集合的末尾添加一个子序列:self[endIndex...]
。
考虑 myFunction
的算法,该算法处理集合的某些部分,可能会跳过某些部分,并返回第一个“重要”部分(即跳过空白的分词器的第一阶段)。 endIndex
自然会告诉您它上次查看的位置,并允许您从该位置开始下一次搜索。从此集合 返回空子序列 意味着索引始终兼容。您始终可以安全地设置 startSearchingFrom = result.endIndex
,即使它是空的。
在大多数情况下,正确设置索引并不重要。但在大多数情况下,您可能只是想在 Array 上使用它,它不需要是通用的。如果你想让它成为通用的,IMO 你应该确保保留你正在处理的类型的所有语义,这意味着让索引正确。
我正在创建 Collection
的扩展,return 是 SubSequence
。但是,如果函数的条件无效,我想 return 一个空的 SubSequence
而不是 nil.
如何在 Collection
的扩展中 return 空 SubSequence
?
// basic example:
extension Collection {
func myFunction(condition: Bool) -> SubSequence {
guard condition else {
return *EmptySubSequence*
}
...
}
}
如果我只是对具体类型进行扩展,这将非常容易,但在我将扩展限制为特定类型之前,我想知道它是否可以应用于 Collection
本身。
我发现的最好的是 prefix(0)
将 return 长度为 0 的 SubSequence
。
如果您需要初始化一个空集合,您应该扩展 RangeReplaceableCollection
而不是 Collection
。 RangeReplaceableCollection
要求符合它的类型实现空初始化器。
extension RangeReplaceableCollection {
func myFunction(condition: Bool) -> SubSequence {
guard condition else {
return .init()
}
// ...
}
}
虽然我相信 Leo 的回答很有帮助,但我不会在这种情况下使用它。不需要增加RangeReplaceableCollection这样的额外需求,它也增加了replaceSubrange
的需求。添加这些要求会限制扩展超出需要。例如,Range 不是 RangeReplaceableCollection。 (如果你真的只打算在 Array 上调用它,那么我建议明确说明并忘记 Collection。)
创建一个“新的”子序列意味着它变得与原始集合无关,并且破坏了索引的含义。调用 init
将创建具有“类似零”起始索引的内容,该索引可能与您正在处理的集合不兼容。您无法安全地比较来自不同集合的索引,即使是相同类型的索引也是如此。
Sweeper 的建议 prefix(0)
更好,但我认为锚定到开头对于需要它的常见算法没有帮助。
相反,我建议在集合的末尾添加一个子序列:self[endIndex...]
。
考虑 myFunction
的算法,该算法处理集合的某些部分,可能会跳过某些部分,并返回第一个“重要”部分(即跳过空白的分词器的第一阶段)。 endIndex
自然会告诉您它上次查看的位置,并允许您从该位置开始下一次搜索。从此集合 返回空子序列 意味着索引始终兼容。您始终可以安全地设置 startSearchingFrom = result.endIndex
,即使它是空的。
在大多数情况下,正确设置索引并不重要。但在大多数情况下,您可能只是想在 Array 上使用它,它不需要是通用的。如果你想让它成为通用的,IMO 你应该确保保留你正在处理的类型的所有语义,这意味着让索引正确。