swift - 当 ElementOfResult 被推断为 Optional 时,flatMap 不会过滤掉 nil

标签 swift functional-programming option-type flatmap

flatMap 的 Swift 文档如下:

Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.

在以下示例中,当返回类型为 ElementOfResult 时留给编译器推断 flatMap按记录工作,但在第 5 行时 ElementOfResult被指定,因此推断为 Optional<String>输入似乎是 flatMap停止过滤掉 nil的。

为什么要这样做?

~ swift
Welcome to Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1). Type :help for assistance.
  1> let words = ["1989", nil, "Fearless", nil, "Red"]
words: [String?] = 5 values {
  [0] = "1989"
  [1] = nil
  [2] = "Fearless"
  [3] = nil
  [4] = "Red"
}
  2> words.flatMap { $0 }
$R0: [String] = 3 values {
  [0] = "1989"
  [1] = "Fearless"
  [2] = "Red"
}
  3> let resultTypeInferred = words.flatMap { $0 }
resultTypeInferred: [String] = 3 values {
  [0] = "1989"
  [1] = "Fearless"
  [2] = "Red"
}
  4> let resultTypeSpecified: [String?] = words.flatMap { $0 }
resultTypeSpecified: [String?] = 5 values {
  [0] = "1989"
  [1] = nil
  [2] = "Fearless"
  [3] = nil
  [4] = "Red"
}

最佳答案

这是 flatMap() 的定义

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

当您设置 resultTypeSpecified 的类型时至 [String?] ,你告诉编译器 ElementOfResultOptional<String> .

你的转换闭包的类型是 (String?) -> Optional<Optional<String>> .

flatMap将带走 1“层”的 optional ,但不会带走 2 层。

希望这个例子能让事情变得更清楚:

let input: [String??] = [
    Optional.some(Optional.some("1989")),
    Optional.some(Optional.none),
    Optional.some(Optional.some("Fearless")),
    Optional.some(Optional.none),
    Optional.some(Optional.some("Red"))
]

let output = input.flatMap({ $0 })

关于swift - 当 ElementOfResult 被推断为 Optional 时,flatMap 不会过滤掉 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42214880/

相关文章:

java - 如何将可选字段(Java 8 API)更改为 Java 7

Scalaz monad 转换器。将 f1 :A => G[B], f2:B => G[C] 函数应用于 F[G[A]] 对象

swift - 在 Swift 中检查可选项的首选方法

ios - 离开并返回 View Controller 后 UIInputViewController 被解雇

swift - 两个 UIView 共享几乎相同的 UIViewController

ios - 如何使用 swift 3.0 以编程方式连接多个 View Controller

swift - 在单元格自定义 TableViewCell 中按下按钮时删除单元格

python - Python 的 "with"是一元的吗?

c++ - 函数式编程在 C++1z 中每三分之一递增整数序列?

arrays - "Initializer for conditional binding must have Optional type, not ' [任意] '"- swift