[swift 进阶]读书笔记-第四章:可选值 1_3 序列_魔法数问题_可选值概览

可选值

4.1哨岗值 Sentinel Value


定义:有的函数可能返回nil 当函数返回nil 我们将返回值 用作-1 等类似的值代替,这样的值就被称为"哨岗值" 也叫魔法数。

4.2通过枚举来解决魔法数的问题


swift中Optional的本质是一个枚举(目前可以先不具体思考,等以后的项目中慢慢就领悟到了)。

enum Optional<Wrapped> {
    case none //为空
    case some(wrapped) // 有值
}

知识点:当返回值为可选值 ? 时,实质上返回的是一个Optional的枚举

    ///返回值为Optional的实质
    let strArray = ["one","two","three"]
    switch strArray.index(of: "four") {
    case .none:
        print("返回值为空") //返回值为空
    case .some(let idx):
        print(idx)
        print("有值")
    }

4.3可选值概览:Optional

if let

相信大家在swift 入门的时候就已经能很好的使用这个语法了。 不赘述。

技巧1: 可与Bool 联合判断

if let obj = Optional , Bool {
    /// 前面有值且后面Bool为true执行
}

技巧2: 多let 并列。 这个在开发中也经常用到

if let obj1 = Optional1, let obj2 = Optional2, ....{
///当上面的let判断都有值的时候执行
}

while let

类似于if let 遇到nil时终止循环
也有和上面👆技巧1(一旦为false 就循环停止,并不是filter那样去工作)相同的使用方法。不赘述。

    while let line = printLine() {
    ///当printLine为空时候终止循环
        print(line)
    }

双重可选值:


一个可选值可能会被另外一个可选值包装起来,形成了可选值的嵌套。你也可以理解成obj?? 。平时在复杂逻辑操作时注意一哈就可以了。

if var 和 while var

和 let 的使用类似。 但你var 出来的obj实际上是一个本地副本 你对obj做任何更改都不会影响原来的值。

 ///if var 的改变不影响原值
        let dict:[String:String]?
        dict = ["key1":"value1"]
        if var varDict = dict {
            varDict["key1"] = "value2"
        }
        print(dict) //Optional(["key1": "value1"])

解包后可选值的作用域

if let obj = Optional {
///obj的作用域
}

注:有时候我们需要提前退出来避免烦人的if嵌套,这个时候 guard let 的优点马上就体现出来了.

///为空提前退出
guard let obj = Optional else{return}

可选链

OC中对nil发送消息,nothing had happened。 在swift中可以通过可选链(Optional chaining)达到一样的效果

那么问题来了,什么是可选链?
可选链 中的可选是?,可以把链理解成swift中的点语法,可以在《swift链式编程》一书中对这个有更深的理解

delegate?.callback() //就是一个可选链。

//当上面的delegate为可选时编译器会发出警告。 确实有值方法会被调用。没有值时候方法不会被调用。

ps. 😂写了这么多年swift的delegate和闭包 直到自己写笔记的时候才发现自己写复杂了(一点swift的优点都没体现出来。。。)

var voidCallback:(()-> Void)?
    
    ///对于闭包调用的两种写法
    //❌不推荐
    if voidCallback != nil {
        voidCallback!()
    }
    
    //✅ 推荐
    voidCallvack?()

多个可选链的调用。下面这个例子简单易懂,不赘述。

extension Int {
    
    var half: Int? {
        guard self > 1 else {return nil}
        return self/2
    }
    
}
///多可选链调用
20.half?.half?.half //Optional(2)

nil合并运算符 ?? (项目中经常会用到!!可以让你的代码写的很优美~)


一开始看到标题nil合并运算符的时候我是😳的。这都是啥啥啥啊。 当我看到 ?? 这个符号时候豁然开朗。两个是一个意思 项目里面已经用过很多次了,百试不爽。

使用场景: 当去解包!一个可选值,且当这个可选值为nil时,我们要去赋一个默认值防止崩溃 这个时候就用到了 ??

    var number: Int?
    number = nil
    String(number ?? 5) //5 

感觉上是和OC 中的 三目运算符 Bool ? A: B 类似
需要强调的是可选值不是指针

可选值map

可选值flatMap(Demo值得借鉴)

上面两小节讲的都是map 和flatMap对于可选值的一个用法。
有一个小demo对于日常开发可以说是有着四两拨千斤的感觉,如下:

    ///将一个网络图片加载出来的奇淫方法!!!
    let urlString = "http://www.objc.io/logo.png"
    let view = URL(string: urlString)
        .flatMap { (url) -> Data? in
        try? Data(contentsOf: url)
        }
        .flatMap { (data) -> UIImage? in
            UIImage(data: data)
        }
        .map { (image) -> UIImageView in
            UIImageView(image: image)
    }
    
    if let view = view {
        UIView().addSubview(view)
    }

利用swift中的$0语法简化上面的代码

    let view2 = URL(string: urlString)
        .flatMap {
            try? Data(contentsOf: $0)
        }
        .flatMap {
            UIImage(data: $0)
        }
        .map {
            UIImageView(image: $0)
    }
    
    if let view2 = view2 {
        UIView().addSubview(view2)
    }

这里的flatMapif let 非常相似。
这样我们就将一个网络图片加载出来了。
想想自己之前写了那么多的垃圾代码,不禁长叹一句:swift🐂🍺!!!

使用flatMap过滤nil

同样这里我们用一个demo去说明用法

目的:我们想要求一个字符串数组中的数字和。

    let numbers = ["1","2","3","4","liaoworking"]
    ///普通青年
    var sum = 0
    for case let i? in numbers.map({
        Int($0)
    }) {
        sum += i// Int($0)为nil就不走这里了
    }
    //        sum的值为10
    
    ///优质青年
    ///当我们用?? 把nil替换成0
    numbers.map { Int($0) }.reduce(0) { $0 + ($1 ?? 0)} //10
    
    ///文艺青年
    ///在标准库中flatMap的作用可能正是你想要
    numbers.flatMap { Int($0) }.reduce(0, +) // 10

注:这里的flatMap的作用:把一个映射为可选值的序列进行展平。

这个例子的确好吊,不自己写一遍不知道还有很多高级用法自己不会。 学习了学习了~

如果让我去面试swift开发。一定会选这个demo做一个面试题!

可选值判等

判等时我们并不关心可选值是不是nil,只用去管它是否包含我们想要的非nil的特定值即可。

switch case 匹配可选值

/// switch case
    let numbers = ["1","2","3","4","liaoworking"]
    for i in numbers {
        switch Int(i) {
        case 0:
            print("0")
        case nil:
            print("can't convert to int")
        default:
            print("not in case")
        }
    }

swift中case匹配是通过~=运算符进行的。 我们可以实现这个方法增加对范围(0..<num)匹配的方法

可选值的比较

和 == 类似 可选值曾经也有 <=, >=, <, >操作符 后来在SE-0121因为安全原因被移除了。

///在一个温度数组中
let temp = ["-23", "0", "66.66", "warm"]

Double("warm") 的值为nil

Double("warm") < 0 是成立的

但你不能说warm是小于0度的是很冷的。

这显然不合情理。

文章源文件地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351