打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Swift学习之路七(可选链 Optional Chaining | LvesLi's Blogging

写在前面

喜欢我们的内容,可以订阅我们的官方微信公众账号:乐Coding。

版权属于: LvesLi’s Blogging

原文地址: http://www.lvesli.com/?p=104

转载时必须以链接形式注明原始出处及本声明。

可选链 Optional Chaining

可选链(Optional Chaining)是一种可以请求和调用属性、方法及下标脚本的过程,它的可选性体现于请求或调用的目标当前可能为空(nil)。如果可选的目标有值,那么调用就会成功;相反,如果选择的目标为空(nil),则这种调用将返回空(nil)。多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(nil)将导致整个链失效。

注意:

Swift 的可选链和 Objective-C 中的消息为空有些相像,但是 Swift 可以使用在任意类型中,并且失败与否可以被检测到。

1.通过在想调用的属性、方法、或下标脚本的可选值(optional value)(非空)后面放一个问号,可以定义一个可选链。这一点很像在可选值后面放一个叹号来强制拆得其封包内的值。它们的主要的区别在于当可选值为空时可选链即刻失败,然而一般的强制解析将会引发运行时错误

调用可选链的返回结果与原本的返回结果具有相同的类型,但是原本的返回结果被包装成了一个可选值,当可选链调用成功时,一个应该返回Int的属性将会返回Int?。

1.1 下面我们通过例子查看可选链与强制解析的不同


//定义一个人
class Person {
//拥有一个可选属性
var card:Card?
}
//定义一个卡片
class Card {
var number=1
}
let lvesli=Person()

//lvesli.card!.number //如果用!强制解析card的number属性将会报运行时错误,因为card的number为nil,没有可以供解析的card

当lvesli.card不是nil时,会运行通过

1.2 利用可选链,使用问号来代替原来!的位置:


var c=lvesli.card?.number
if c==nil{
println("can't get card number")

}else{
println("CarNumber : \(c)")
}
//打印 can't get card number

只要是通过可选链的请求就意味着最后number总是返回一个Int?而不是Int。

2. 为可选链定义模型类

你可以使用可选链来多层调用属性,方法,和下标脚本。这让你可以利用它们之间的复杂模型来获取更底层的属性,并检查是否可以成功获取此类底层属性。


class Student {
var build:Building?
var name:String?
init(name:String){
self.name=name
}
}
class Building {
//房间数组
var rooms=[Room]()
//房间的个数
var numberOfRoom:Int{
return rooms.count
}
//定义下表脚本
subscript (i:Int)->Room{
return rooms[i]
}
func printNumberOfRooms(){
println("The number of rooms is \(numberOfRoom)")
}
//地址可选属性
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
}
}
}

2.1通过可选链调用属性

let lves=Student(name: "lves")
let roomCount=lves.build?.numberOfRoom
if roomCount==nil{
println("NO room")
}else{
println("\(lves.name)'s building has \(roomCount) room")
}

//打印 NO room
2.2通过可选链调用方法
building 的printNumberOfRooms()函数没有返回值。但是,没有返回值类型的函数和方法有一个隐式的返回值类型Void

如果你利用可选链调用此方法,这个方法的返回值类型将是Void?,而不是Void,因为当通过可选链调用方法时返回值总是可选类型(optional type)。即使这个方法本身没有定义返回值,你也可以使用if语句来检查是否能成功调用printNumberOfRooms方法:如果方法通过可选链调用成功,printNumberOfRooms的隐式返回值将会是Void,如果没有成功,将返回nil:

if lves.build?.printNumberOfRooms?() {
println("It was possible to print the number of rooms.")
} else {
println("It was not possible to print the number of rooms.")
}
//打印 "It was not possible to print the number of rooms."。

2.3 你可以使用可选链来尝试从下标脚本获取值并检查下标脚本的调用是否成功,然而,你不能通过可选链来设置下标脚本。

注意:

当你使用可选链来获取下标脚本的时候,你应该将问号放在下标脚本括号的前面而不是后面。可选链的问号一般直接跟在表达语句的后面。

var firstRoomName = lves.build?[0].name
if firstRoomName==nil{
println("Unable to get the first room name.")
} else {
println("The first room name is \(firstRoomName).")
}
// 打印 "Unable to get the first room name."。

2.4 连接多层链接

你可以将多层可选链连接在一起,可以掘取模型内更下层的属性方法和下标脚本。然而多层可选链不能再添加比已经返回的可选值更多的层。 也就是说:

如果你试图获得的类型不是可选类型,由于使用了可选链它将变成可选类型。 如果你试图获得的类型已经是可选类型,由于可选链它也不会提高可选性。
因此:

如果你试图通过可选链获得Int值,不论使用了多少层链接返回的总是Int?。 相似的,如果你试图通过可选链获得Int?值,不论使用了多少层链接返回的总是Int?。


let street=lves.build?.address?.street //nil
let lvesAddress = Address()
lvesAddress.buildingName = "微软大厦"
lvesAddress.street = "善缘街"
//lves.build!.address=lvesAddress
let street2=lves.build?.address

链接可选返回值的方法

let identifier=lves.build?.address?.buildingIdentifier() //nil
let upIdentifier=lves.build?.address?.buildingIdentifier()?.uppercaseString

喜欢我们的内容,搜索官方微信账号:乐Coding。投稿请发送到:lvesli@163.com。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Swift 可选链
深入解析Swift语言编程中的可选链
【Go Slice详解】读者纷纷表示终于理解了cap
iOS开发系列--Swift语言
在Swift中自定义下标(Subscripts) | Let's Swift
Swift学习这二十二:扩展(extension)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服