下面是一些操场代码,我用它来探索Array实现Sequence协议的flatMap()方法的行为。我惊讶地发现将callFlatmap的数组参数声明为Any of Array的结果是flatMap将变量闭包的参数包装在一个可选项中。这是设计的行为吗?
func echo<T>(_ arg: T) -> T {
print("arg = \(arg)")
return arg
}
func callFlatten(_ array: Array<Any>) {
print("Input: \(array)")
print("Result: \(array.flatMap{ echo($0) })\n\n")
}
var array = [[1, 2], [3, 4], [5, 6]]
callFlatten(array)
/* Prints:
Input: [[1, 2], [3, 4], [5, 6]]
arg = Optional([1, 2])
arg = Optional([3, 4])
arg = Optional([5, 6])
Result: [[1, 2], [3, 4], [5, 6]]
*/
print("Input: \(array)")
print("Result: \(array.flatMap{ echo($0) })\n\n")
/* Prints:
Input: [[1, 2], [3, 4], [5, 6]]
arg = [1, 2]
arg = [3, 4]
arg = [5, 6]
Result: [1, 2, 3, 4, 5, 6]
*/
答案 0 :(得分:1)
Array
有两种flatMap
方法:
/// Returns an array containing the concatenated results of calling the
/// given transformation with each element of this sequence.
public func flatMap<SegmentOfResult : Sequence>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element]
和
/// Returns an array containing the non-`nil` results of calling the given
/// transformation with each element of this sequence.
public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
在
var array = [[1, 2], [3, 4], [5, 6]]
// ...
print("Result: \(array.flatMap{ echo($0) })\n\n")
// Result: [1, 2, 3, 4, 5, 6]
调用第一个方法,因为数组元素类型是已知的
成为一个数组,因此是Sequence
。调用echo($0)
每个元素,结果是内部数组的连接。
在
func callFlatten(_ array: Array<Any>) {
print("Input: \(array)")
print("Result: \(array.flatMap{ echo($0) })\n\n")
}
callFlatten(array)
// Result: [[1, 2], [3, 4], [5, 6]]
对元素类型和第二种方法一无所知
叫做。
为了匹配闭包的返回类型ElementOfResult?
,
T
echo
的通用占位符类型被推断为
Any?
和$0
被提升为可选项。
结果是一个具有echo($0)
的非零结果的数组 - 它们正是数组元素。结果的类型为Array<Any>
。