Swift 1.2中可选展开的Map和flatMap差异

Dán*_*agy 3 dictionary bind optional flatmap swift

双方mapflatMap都defind上ImplicitlyUnwrappedOptional,但他们根据不同的文件(显然)在他们的定义:

func map(f:@noescape(T) - > U) - > U!

如果self == nil,则返回nil.否则,返回f(self!).

func flatMap(f:@noescape(T) - > U!) - > U!

返回f(自我)!iff self和f(self)不是nil.

我尝试使用它们的一个简单示例:

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
Run Code Online (Sandbox Code Playgroud)

但是,他们生产的相同的结果,即使numbernil. 我的问题是,它们之间有什么实际的区别,如果我申请mapflatMapImplicitlyUnwrappedOptionalS' 我应该选择哪一个以及何时?

Mar*_*n R 7

flatMap(),映射闭包具有类型(T) -> U?,可以返回nil:

let res3 = number.flatMap { $0 == 1 ? nil : 2 }.flatMap { $0 + 1 }
res3 // nil
Run Code Online (Sandbox Code Playgroud)

map()对于映射闭包具有签名的位置,这是不可能的(T) -> U.

更现实的例子是将可选字符串转换为可选整数:

func foo(s : String?) -> Int? {
    return s.flatMap { $0.toInt() }
}
foo("1") // 1
foo("x") // nil (because `toInt()` returns nil)
foo(nil) // nil (because argument is nil)
Run Code Online (Sandbox Code Playgroud)


mat*_*att 7

map()在映射闭包具有签名的情况下是不可能的(T) -> U

这不太对。在我看来,马丁的r的答案并不完全知道问题的心脏,这是该文档不正确描述之间的差异mapflatMap

区别在于他们采取什么样的关闭方式。每个人都会高兴地接受一个产生 nonOptional 的闭包或一个产生 Optional 的闭包——不管文档怎么说,尽管他们的声明有所不同。所有这些表达式编译:

let i : Int? = nil
let result1 = i.map {_ in "hello"} // map, closure produces nonOptional
let result2 = i.flatMap {_ in "hello"} // flatMap, closure produces nonOptional
let result3 = i.map {_ in Optional("hello") } // map, closure produces Optional
let result4 = i.flatMap {_ in Optional("hello") } // flatMap, closure produces Optional
Run Code Online (Sandbox Code Playgroud)


好的,那么实际的区别是什么?这是flatMap为了防止闭包确实产生一个 Optional:它解开它,从而防止双重包装的 Optional:

let i : Int? = nil
let result1 = i.map {_ in "hello"} // String?
let result2 = i.flatMap {_ in "hello"} // String?
let result3 = i.map {_ in Optional("hello") } // String?? // double-wrapped
let result4 = i.flatMap {_ in Optional("hello") } // String? // not double-wrapped
Run Code Online (Sandbox Code Playgroud)

这是map 和 flatMap 之间的唯一区别。