Map and flatMap difference in optional unwrapping in Swift 1.2(SWIFT 1.2中可选展开中的Map和Flat Map差异)
问题描述
map
和flatMap
都是在ImplicitlyUnwrappedOptional
上发现的,但根据文档,它们的定义(明显)不同:
函数映射(f:@noscape(T)->;U)->;U! 如果self==nil,则返回nil。否则,返回f(self!)。
函数平面映射(f:@noscape(T)->;U!)->;U!
返回f(自身)!如果f self和f(Self)不为零。
我用一个简单的例子尝试使用它们:
let number: Int? = 1
let res1 = number.map { $0 + 1 }.map { $0 + 1 }
let res2 = number.flatMap { $0 + 1 }.flatMap { $0 + 1 }
res1 //3
res2 //3
但即使number
为nil.
,它们也会产生相同的结果
所以我的问题是,如果我将map
或flatMap
应用于ImplicitlyUnwrappedOptional
,它们之间的实际区别是什么?我应该选择哪一个以及何时选择另一个?
推荐答案
(备注:答案已更新,以反映SWIFT 3及更高版本中的语法更改,例如取消ImplicitlyUnwrappedOptional
。)
Optional.map()
和Optional.flatMap()
声明如下(我省略了此处不相关的抛出/重新抛出修饰符):
func map<U>(_ transform: (Wrapped) -> U) -> U?
func flatMap<U>(_ transform: (Wrapped) -> U?) -> U?
让我们考虑使用"map"的第一个示例的简化版本:
let number: Int? = 1
let res1 = number.map { $0 + 1 }
print(res1) // Optional(2)
number
类型为Int?
,闭包类型推断为(Int) -> Int
。U
为Int
,返回值类型为Int?
。number
不是nil
,因此它被解包并传递1
到闭包。闭包返回2
,map
返回Optional(2)
。如果number
为nil
,则结果将为nil
。
现在我们考虑您的第二个示例的一个简化版本,其中包含"flatMap":
let number: Int? = 1
let res2 = number.flatMap { $0 + 1 }
print(res2) // Optional(2)
flatMap
应为(Wrapped) -> U?
类型的闭包,但{ $0 + 1 }
不返回可选的。为了使其进行编译,编译器将其转换为
let res2 = number.flatMap { return Optional($0 + 1) }
现在闭包的类型是(Int) -> Int?
,U
又是Int
。同样,number
被解包并传递给闭包。闭包返回Optional(2)
,这也是flatMap
的返回值。如果number
为nil
或如果闭包将返回nil
,则结果将为nil
。
因此这些调用之间确实没有区别:
let res1 = number.map { $0 + 1 }
let res2 = number.flatMap { $0 + 1 }
然而,这并不是flatMap
的目的。一个更现实的例子是
func foo(_ s : String?) -> Int? {
return s.flatMap { Int($0) }
}
print(foo("1")) // Optional(1)
print(foo("x")) // nil (because `Int($0)` returns nil)
print(foo(nil)) // nil (because the argument is nil)
通常,map
接受(Wrapped) -> U
类型的闭包并转换
Optional<Wrapped>.none --> Optional<U>.none
Optional<Wrapped>.some(wrapped) --> Optional<U>.some(transform(wrapped))
flatMap
接受(Wrapped) -> U?
类型的闭包并转换
Optional<Wrapped>.none --> Optional<U>.none
Optional<Wrapped>.some(wrapped) --> transform(wrapped)
此处transform(wrapped)
也可以是Optional<U>.none
。
如果使用闭包调用flatMap
,而不返回可选的,则编译器会自动将其转换为可选的,并且map
与map
没有区别。
这篇关于SWIFT 1.2中可选展开中的Map和Flat Map差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:SWIFT 1.2中可选展开中的Map和Flat Map差异
基础教程推荐
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01