Swift4 基础部分: Optional Chaining(可选链)

本文是学习《The Swift Programming Language》整理的相关随笔,基本的语法不作介绍,主要介绍Swift中的一些特性或者与OC差异点。

系列文章:

可选链可替代强制解析(Optional Chaining as an Alternative to Forced Unwrapping)

You specify optional chaining by placing a question mark 
(?) after the optional value on which you wish to call a 
property, method or subscript if the optional is non-nil. 
This is very similar to placing an exclamation mark (!) 
after an optional value to force the unwrapping of its 
value. The main difference is that optional chaining fails 
gracefully when the optional is nil, whereas forced 
unwrapping triggers a runtime error when the optional is 
nil.
  • 在想调用的属性、方法、或下标脚本的可选值后面放一个?,可以定义一个可选链。这很像在可选值后面放一个!来强制拆得其封包内的值。它们的主要的区别在于当可选值为空时可选链即刻失败,然而一般的强制解析将会引发运行时错误。

例子:

class Residence {
    var numberOfRooms = 1;
}

class Person {
    var residence: Residence?;
}
let john = Person();
let rootCount = john.residence!.numberOfRooms;

执行结果:

fatal error: unexpectedly found nil while unwrapping an Optional value

我们改写成可选链的方式去访问numberOfRooms:

let john = Person();
if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).");
}else{
    print("Unable to retrieve the number of rooms.");
}

执行结果:

Unable to retrieve the number of rooms.

通过可选链调用属性(Accessing Properties Through Optional Chaining)

例子:

class Person {
    var residence: Residence?;
}

class Residence {
    var rooms = [Room]();
    var numberOfRooms: Int {
        return rooms.count;
    }
    subscript(i: Int) -> Room {
        return rooms[i];
    }
    func printNumberOfRooms() {
        print("The number of rooms is \(numberOfRooms)");
    }
    var address: Address?;
}

class Room {
    let name: String;
    init(name: String) { self.name = name; }
}

class Address {
    var buildingName: String?;
    var buildingNumber: String?;
    var street: String?;
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName;
        } else if (buildingNumber != nil) {
            return buildingNumber;
        } else {
            return nil;
        }
    }
}

let john = Person();
if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).");
} else {
    print("Unable to retrieve the number of rooms.");
}

john.residence = Residence();
if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).");
} else {
    print("Unable to retrieve the number of rooms.");
}

执行结果:

Unable to retrieve the number of rooms.
John's residence has 0 room(s).

通过可选链调用方法(Calling Methods Through Optional Chaining)

You can use optional chaining to call a method on an optional value, 
and to check whether that method call is successful. You can do this 
even if that method does not define a return value.
  • 可以使用可选链来调用方法去判断是否方法调用成功。即使该方法没有返回值。

例子:

let john = Person();
john.residence = Residence();
if john.residence?.printNumberOfRooms() != nil {
    print("It was possible to print the number of rooms.")
} else {
    print("It was not possible to print the number of rooms.")
}

执行结果:

It was possible to print the number of rooms.

使用可选链调用下标脚本(Accessing Subscripts Through Optional Chaining)

You can use optional chaining to try to retrieve and set a value from a 
subscript on an optional value, and to check whether that subscript 
call is successful.
  • 可以使用可选链尝试从下标脚本获取值并且检查是否调用成功。

例子:

let john = Person();
john.residence = Residence();
let room:Room = Room(name:"xz");
john.residence?.rooms.append(room);
if let firstRoomName = john.residence?[0].name {
    print("The first room name is \(firstRoomName).")
} else {
    print("Unable to retrieve the first room name.")
}

执行结果:

The first room name is xz.

连接多层链接(Linking Multiple Levels of Chaining)

You can link together multiple levels of optional chaining to drill 
down to properties, methods, and subscripts deeper within a model. 
However, multiple levels of optional chaining do not add more levels of 
optionality to the returned value.
  • 可以将多层可选链连接在一起,可以掘取模型内更下层的属性方法和下标脚本。然而多层可选链不能再添加比已经返回的可选值更多的层。

例子:

let john = Person();
john.residence = Residence();
john.residence?.address = Address();
john.residence?.address?.street = "beijing road";
if let johnsStreet = john.residence?.address?.street {
    print("John's street name is \(johnsStreet).");
} else {
    print("Unable to retrieve the address.");
}

执行结果:

John's street name is beijing road.

链接可选返回值的方法(Chaining on Methods with Optional Return Values)

例子:

let john = Person();
john.residence = Residence();
john.residence?.address = Address();
john.residence?.address?.street = "beijing road";
john.residence?.address?.buildingName = "beijing building";

if let buildingIdentifier = john.residence?.address?.buildingIdentifier()?.uppercased() {
    print("John's building identifier is \(buildingIdentifier).");
}

执行结果:

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

推荐阅读更多精彩内容