当ElementOfResult被推断为可选时,flatMap不会过滤掉nil [英] flatMap does not filter out nil when ElementOfResult is inferred to be Optional

查看:159
本文介绍了当ElementOfResult被推断为可选时,flatMap不会过滤掉nil的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Swift的flatMap文档读取:


返回一个包含调用给定
变换的非零结果的数组,

$ b

在下面的例子中,当< >留给编译器以推断 flatMap 按记录工作,但在第5行中指定了 ElementOfResult 时,因此推断到可选< String> 类型,似乎 flatMap 停止过滤 nil 的。



为什么要这样做?

 〜swift 
欢迎使用Apple Swift 3.0.2版(swiftlang-800.0.63 clang-800.0.42.1)。类型:帮助寻求帮助。
1> let words = [1989,nil,Fearless,nil,Red]
words:[String?] = 5 values {
[0] =1989
[ 1] =无
[2] =无畏
[3] =无
[4] =红
}
2> words.flatMap {$ 0}
$ R0:[String] = 3 values {
[0] =1989
[1] =霍元甲
[2] = 红
}
3> let resultTypeInferred = words.flatMap {$ 0}
resultTypeInferred:[String] = 3 values {
[0] =1989
[1] =Fearless
[2 ] =红色
}
4> let resultTypeSpecified:[String?] = words.flatMap {$ 0}
resultTypeSpecified:[String?] = 5 values {
[0] =1989
[1] = nil
[2] =无畏
[3] =无
[4] =红色
}

解决方案

以下是定义 flatMap()

$ b $ (元素)抛出 - > ElementOfResult?)rethrows - > b>< b> [ElementOfResult]


设置 resultTypeSpecified [String?] ,你告诉编译器 ElementOfResult 可选<字符串>



变换闭包的类型为(String?) - >任选的LT;任选的LT;字符串>>



flatMap 将带走1层可选层,而不是2层。 b

希望这个例子能够让事情变得更加清晰:

  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 documentation of flatMap reads:

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

In the following examples when return type of ElementOfResult is left to the compiler to infer flatMap works as documented, yet on line 5 when ElementOfResult is specified, thus inferred to an Optional<String> type it seems that flatMap stops filtering out nil's.

Why is it doing that?

~ 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"
}

解决方案

Here's the definition of flatMap()

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

When you set the type of resultTypeSpecified to [String?], you tell the compiler that ElementOfResult is Optional<String>.

Your transform closure has a type of (String?) -> Optional<Optional<String>>.

flatMap will take away 1 "layer" of optionals but not 2 layers.

Hopefully this example will makes things clearer:

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 })

这篇关于当ElementOfResult被推断为可选时,flatMap不会过滤掉nil的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆