【问题标题】:Why does flatMap used via an extension return different results than when called directly?为什么通过扩展使用的 flatMap 与直接调用时返回的结果不同?
【发布时间】:2017-06-22 19:53:27
【问题描述】:

考虑这段代码...

import Foundation

let source = ["A", "B", nil, "D"]
print(type(of:source))

let result1 = source.flatMap{ $0 }
print(type(of:result1))
print(result1)

extension Array
{
    func sameThing() -> Array
    {
        return self.flatMap{ $0 }
    }
}

let result2 = source.sameThing()
print(type(of:result2))
print(result2)

result1Array<String>,而 result2Array<Optional<String>>。但为什么呢?

我尝试过使用序列而不是数组,但也没有运气。

【问题讨论】:

标签: arrays swift sequence flatmap


【解决方案1】:

您的返回类型保留泛型类型

func sameThing(separator:String = " ") -> Array

因此,此操作的可选元素签名等价于[T?] -> [T?]

Sequence.flatMap 有两个带有特制签名的重载

func flatMap<SegmentOfResult : Sequence>(
    _ transform: (${GElement}) throws -> SegmentOfResult
) rethrows -> [SegmentOfResult.${GElement}]

func flatMap<ElementOfResult>(
    _ transform: (${GElement}) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {

第二个获胜。但是由于您要求提供选项数组,ElementOfResult 变为 Optional&lt;String&gt;transform 变为 Optional&lt;String&gt; -&gt; Optional&lt;Optional&lt;String&gt;&gt;

因此,当闭包{ $0 } 返回nil 时,它被提升到Optional(nil),即具有.some(nil) 值,而不是.none。然后它将通过 nil 守卫并出现在结果中。

【讨论】:

  • 有趣!我一直忘记 Swift 如何使用返回类型作为签名的一部分,而 C# 等其他语言则没有。也就是说,我将如何修改我的函数以完全匹配 flatMap 返回的内容?我正在尝试封装一些功能——其中 flatMap 是其中的一部分——所以我可以重用它。有点难住了。
猜你喜欢
  • 2021-08-03
  • 2018-08-03
  • 2020-10-17
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
相关资源
最近更新 更多