如何 return Swift 中的通用集合或迭代器?
How to return a generic collection or iterator in Swift?
我正在尝试做这样的事情:
func fullOrSubarray(array: [Int]) -> ReturnType {
return array.count < 10 ? array : array[0..<10]
}
当我尝试 return Array<Int>
或 ArraySlice<Int>
时,我应该将什么写入 ReturnType
?
我知道我可以简单地将 ArraySlice<Int>
转换为 Array<Int>
(反之亦然),但出于性能原因我不想这样做。我想要 return 一些通用集合或迭代器类型,但 Swift 似乎没有。我是否必须为这样的事情编写自定义迭代器?其他语言有各种通用迭代器,所以我可以 return 数组、集合等互换。
您描述的情况是有可能发生的,但首先,您应该看看是否可以避免。您给出的具体示例正是 prefix
并且绝对应该实现为:
func fullOrSubarray(array: [Int]) -> ArraySlice<Int> {
array.prefix(10)
}
这里 return 正确的是 ArraySlice。没有理由 return 其他东西。查看 implementation of prefix
以了解 stdlib 如何处理此问题。
也就是说,在极少数情况下,执行您所描述的操作可能会有用。例如,底层数据可能位于 Set 或 Array 中,您希望避免副本。在这种情况下,正确的工具是 AnySequence 或 AnyCollection:
func fullOrSubarray(array: [Int]) -> AnySequence<Int> {
array.count < 10 ? AnySequence(array) : AnySequence(array[0..<10])
}
但这是一种非常不寻常的情况,永远不会用于 Array 和 ArraySlice。为此,只需使用 ArraySlice,或转换回 Array。不要假设从切片到数组的转换很昂贵。 stdlib 在内部写时复制数组缓冲区方面非常聪明,通常可以避免制作任何副本。
即使在数据当前可能是一个集合的情况下,除非它非常大或经常访问,通常最好在 return 将其转换为数组之前将其转换为数组。如果它经常作为数组访问,我倾向于首先将其存储为数组而不是集合。
但如果所有这些都让您失望,并且您需要 return 一个未知的序列类型,这就是 AnySequence(或 AnyCollection)的用途。
我正在尝试做这样的事情:
func fullOrSubarray(array: [Int]) -> ReturnType {
return array.count < 10 ? array : array[0..<10]
}
当我尝试 return Array<Int>
或 ArraySlice<Int>
时,我应该将什么写入 ReturnType
?
我知道我可以简单地将 ArraySlice<Int>
转换为 Array<Int>
(反之亦然),但出于性能原因我不想这样做。我想要 return 一些通用集合或迭代器类型,但 Swift 似乎没有。我是否必须为这样的事情编写自定义迭代器?其他语言有各种通用迭代器,所以我可以 return 数组、集合等互换。
您描述的情况是有可能发生的,但首先,您应该看看是否可以避免。您给出的具体示例正是 prefix
并且绝对应该实现为:
func fullOrSubarray(array: [Int]) -> ArraySlice<Int> {
array.prefix(10)
}
这里 return 正确的是 ArraySlice。没有理由 return 其他东西。查看 implementation of prefix
以了解 stdlib 如何处理此问题。
也就是说,在极少数情况下,执行您所描述的操作可能会有用。例如,底层数据可能位于 Set 或 Array 中,您希望避免副本。在这种情况下,正确的工具是 AnySequence 或 AnyCollection:
func fullOrSubarray(array: [Int]) -> AnySequence<Int> {
array.count < 10 ? AnySequence(array) : AnySequence(array[0..<10])
}
但这是一种非常不寻常的情况,永远不会用于 Array 和 ArraySlice。为此,只需使用 ArraySlice,或转换回 Array。不要假设从切片到数组的转换很昂贵。 stdlib 在内部写时复制数组缓冲区方面非常聪明,通常可以避免制作任何副本。
即使在数据当前可能是一个集合的情况下,除非它非常大或经常访问,通常最好在 return 将其转换为数组之前将其转换为数组。如果它经常作为数组访问,我倾向于首先将其存储为数组而不是集合。
但如果所有这些都让您失望,并且您需要 return 一个未知的序列类型,这就是 AnySequence(或 AnyCollection)的用途。