本文是學(xué)習(xí)《The Swift Programming Language》整理的相關(guān)隨筆属划,基本的語法不作介紹雀哨,主要介紹Swift中的一些特性或者與OC差異點(diǎn)埋凯。
系列文章:
- Swift4 基礎(chǔ)部分:The Basics
- Swift4 基礎(chǔ)部分:Basic Operators
- Swift4 基礎(chǔ)部分:Strings and Characters
- Swift4 基礎(chǔ)部分:Collection Types
- Swift4 基礎(chǔ)部分:Control Flow
- Swift4 基礎(chǔ)部分:Functions
- Swift4 基礎(chǔ)部分:Closures
- Swift4 基礎(chǔ)部分: Enumerations
- Swift4 基礎(chǔ)部分: Classes and Structures
- Swift4 基礎(chǔ)部分: Properties
- Swift4 基礎(chǔ)部分: Methods
- Swift4 基礎(chǔ)部分: Subscripts
- Swift4 基礎(chǔ)部分: Inheritance
- Swift4 基礎(chǔ)部分: Initialization
- Swift4 基礎(chǔ)部分: Deinitialization
- Swift4 基礎(chǔ)部分: Automatic Reference Counting(自動引用計(jì)數(shù))
可選鏈可替代強(qiáng)制解析(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.
- 在想調(diào)用的屬性锅减、方法脆诉、或下標(biāo)腳本的可選值后面放一個?甚亭,可以定義一個可選鏈。這很像在可選值后面放一個!來強(qiáng)制拆得其封包內(nèi)的值击胜。它們的主要的區(qū)別在于當(dāng)可選值為空時可選鏈即刻失敗亏狰,然而一般的強(qiáng)制解析將會引發(fā)運(yùn)行時錯誤。
例子:
class Residence {
var numberOfRooms = 1;
}
class Person {
var residence: Residence?;
}
let john = Person();
let rootCount = john.residence!.numberOfRooms;
執(zhí)行結(jié)果:
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.");
}
執(zhí)行結(jié)果:
Unable to retrieve the number of rooms.
通過可選鏈調(diào)用屬性(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.");
}
執(zhí)行結(jié)果:
Unable to retrieve the number of rooms.
John's residence has 0 room(s).
通過可選鏈調(diào)用方法(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.
- 可以使用可選鏈來調(diào)用方法去判斷是否方法調(diào)用成功偶摔。即使該方法沒有返回值暇唾。
例子:
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.")
}
執(zhí)行結(jié)果:
It was possible to print the number of rooms.
使用可選鏈調(diào)用下標(biāo)腳本(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.
- 可以使用可選鏈嘗試從下標(biāo)腳本獲取值并且檢查是否調(diào)用成功。
例子:
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.")
}
執(zhí)行結(jié)果:
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.
- 可以將多層可選鏈連接在一起啰挪,可以掘取模型內(nèi)更下層的屬性方法和下標(biāo)腳本信不。然而多層可選鏈不能再添加比已經(jīng)返回的可選值更多的層。
例子:
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.");
}
執(zhí)行結(jié)果:
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).");
}
執(zhí)行結(jié)果:
John's building identifier is BEIJING BUILDING.