为什么Array <any> .flatMap()将Transform Closure Arguments包装在一个Optional中?

时间:2017-03-22 19:35:34

标签: arrays swift

下面是一些操场代码,我用它来探索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]
*/

1 个答案:

答案 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>