swift 文章收集swift相关Swift从新手到开发之路

Swift中Optional的map和flatMap

2016-07-12  本文已影响473人  liushuaikobe

用过Swift的读者想必对mapflatMap不陌生,它们定义在SequenceType协议及其extension中,讲它们用法的文章一大堆,我就不拾人牙慧了。

但是不知读者是否知道,Swift中的Optional类型,也有mapflatMap方法。

首先看这样的场景:

    let avatarURL: String? = "http://blog.liushuaiko.be/images/avatar.PNG"

不妨假设avatarURL的来源以及是否有值我们不得而知,因此我们将其定义为一个Optional<String>类型。在使用它时,我们需要做一系列的判断赋值:

    if let _avatarURL = avatarURL {
        if let url = NSURL(string: _avatarURL) {
            print(url.absoluteString)
        }
    }

这样的场景通常在解析网络请求返回的JSON时很常见,不知不觉就出现了所谓的「大括号阶梯」。

我们可以用Optional类型中定义的mapflatMap来避免这种情况,先看下用了之后会变成什么样子:


    avatarURL.flatMap {
        return NSURL(string: $0)
    }.map {
        print($0.absoluteString)
    }

打开Optional的定义,mapflatMap一览无余,你应该顺便发现,Optional在Swift里是一个enum。

去掉@noescapethrows,它们的原型更加清晰:


    public func map<U>(f: Wrapped -> U) -> U?

    public func flatMap<U>(f: Wrapped -> U?) -> U?
 

在这两个泛型函数中,Wrapped是Optional的泛型参数,即Optional包裹的类型。两个函数唯一的不同是接收的参数「函数的返回值」不同,一个期待函数返回U,另一个期待函数返回U?

两个函数在表现上是类似的,如果可选类型有值(!= nil),则返回f(Wrapped Value),否则直接返回nil。

那么不难理解前面的例子:


    let url:NSURL? = avatarURL.flatMap {
        return NSURL(string: $0) // NSURL? 相当于 U?
    }

    let nothing:Optional = url.map {
        print($0.absoluteString) // 什么都不返回,因此这个map返回一个什么都不包裹的Optional
    }

上一篇下一篇

猜你喜欢

热点阅读