Swift 紧凑地图的语法解释

Swift syntax explanation with compact map

我在检查代码时确实发现了以下代码:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return super.layoutAttributesForElements(in: rect)?
            .compactMap { [=11=].copy() as? ParallaxLayoutAttributes }
            .compactMap(prepareAttributes)
    }

    private func prepareAttributes(attributes: ParallaxLayoutAttributes) -> ParallaxLayoutAttributes {
        // Lot of code doing stuff with attributes 
        return attributes
    }

所以,其实我想问的是,compact函数声明如下:

@inlinable public func compactMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

在这个例子中,我们只传递函数,不带参数:

.compactMap(prepareAttributes)

这完全颠覆了我的想法,因为,好吧,prepareAttributes 函数声明如下(必须传递参数):

private func prepareAttributes(attributes: ParallaxLayoutAttributes) -> ParallaxLayoutAttributes

那么,为什么上面的代码可以编译以及具体是如何编译的 .compactMap(prepareAttributes) 当您没有为 prepareAttributes 函数传递参数时运行?

在调用 .compactMap(prepareAttributes) 中,您将函数 prepareAttributes 作为闭包传递给 compactMap。由于 prepareAttributes 接受一个类型与 compactMap 的闭包变量匹配的输入参数,编译器可以自动推断它需要将 [=17=] 传递给 prepareAttributes

所以本质上,.compactMap(prepareAttributes) 是 shorthand 对于

.compactMap {prepareAttributes(attributes: [=10=]) }

map 相同行为的一个简单示例是经常使用的 map 类型,然后将其传递给 init,您可以将其写为 .map { MyType(input: [=22= ]) } 或简化为 .map(MyType.init).

struct MyInt {
    let value: Int

    init(value: Int) {
        self.value = value
    }
}

let ints = [1,2,3]
let myInts = ints.map(MyInt.init) // same as `ints.map { MyInt(value: [=11=]) }