码迷,mamicode.com
首页 > Web开发 > 详细

如何学习Swift可空链式调用

时间:2016-07-14 12:15:01      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:

今天我们一起来学习Swift可空链式调用可空链式调用是一种可以请求和调用属性、方法以及下标的过程,它的可空体现在请求或调用的目标当前可能为nil。如果可空的目标有值,即调用就会成功;如果选择的目标为nil,即调用将返回nil。多个连续的调用可以被链接在一起形成一个调用链,如果其中任何一个节点为nil将导致整个链调用失败。 
 
一、使用可空链式调用来强制展开 
 
可空链的定义,即是在要调用非空的属性、方法、下标的可空值后面添加一个问号即可。特别的,可空链式调用的返回结果与原本的返回结果具有相同的类型,但是被包装成了一个可空类型值,当可空链式调用成功时,一个本该返回Int类型的结果将返回Int?类型。 
class Person { 
   // 可空属性,类型为Student? 
   var student:Student? 
} 
class Student { 
   var name = "xxx" 
} 
let zhangsan = Person()// 这是错误的,因为zhangsan.student现在是为`nil`//let name = zhangsan.student!.name 
// 可空链式调用,即是使用`?`来代替`!`// 即是说,只有当student不为空的时候才访问namelet name1 = zhangsan.student?.name// 另外`var student:Student?`,如果student是为`nil`,那么返回的name也是可空类型的,虽然在定义的时是`var name = "xxx"`if name1 == nil { 
   print("zhangsan --- Student没有进行实例化,即没有名字") 
} else { 
   print("zhangsan --- \(name1)") 
} 
let lisi = Person()// 注意,只要有作实例化操作,那么lisi.student就不是为`nil` 
lisi.student = Student()let name2 = lisi.student?.nameif name2 == nil { 
   print("lisi --- Student没有进行实例化,即没有名字") 
} else { 
   print("lisi --- \(name2!)") 
输出结果: 
zhangsan --- Student没有进行实例化,即没有名字 
lisi --- xxx 
二、为可空链式调用定义模型类 
 
通过使用可空链式调用可以调用多层属性、方法、下标。这可以通过各种模型向下访问各种子属性,并且判断能否访问子属性中的属性、方法、下标。 
// 人类class Person { 
   // 一个人,不一定就有房子,即是可空的 
   var residence:Residence? 
} 
// 房子类class Residence { 
   // 房间数组 
   var rooms = [Room]() 
   // 房间个数 
   var numberOfRoos:Int { 
       return rooms.count 
   } 
   // 下标脚本,下标快捷访问数组rooms 
   subscript(i:Int) -> Room { 
       get { 
           return rooms 
       } 
       set { 
           rooms = newValue 
       } 
   } 
 
   // 打印房子中房间数量函数 
   func printNumberOfRooms() { 
       print("这个房子有\(numberOfRoos)个房间") 
   } 
} 
// 房间类class Room { 
   let name:String 
   init(name:String) { 
       self.name = name 
   } 
} 
// 地址类class Address { 
   // 房子建造者的名字,可空属性 
   var buildingName:String? 
   // 房子建造者的联系方法,可空属性 
   var buildingTell:String? 
   // 房子所在位置,可空属性 
   var street:String? 
 
   // 房子建造的相关信息 
   func buildingIdentifier() -> String? { 
       if buildingName != nil { 
           return buildingName 
       } else if buildingTell != nil { 
           return buildingTell 
       } else { 
           return nil 
       } 
   } 
} 
三、通过可空链式调用来访问属性 
 
根据上面创建的类,实例操作来进行访问对应属性: 
// 实例化Personlet endEvent = Person()// 注意Residence`nil`,那么可空链式调用失败if let roomCount = endEvent.residence?.numberOfRoos { 
   print("EndEvent房子中有\(roomCount)个房间") 
} else { 
   print("Residence没有进行实例化操作") 
} 
// 实例化Addresslet guangzhou = Address() 
guangzhou.buildingName = "xxx" 
guangzhou.street = "体育中心" 
guangzhou.buildingTell = "xxx-xxx-xxx"// 通过可空链式调用来设置属性值// 但是此时设置是失败的,因为endEvent.residence为空 
endEvent.residence?.address = guangzhou// 打印是为`nil`print(endEvent.residence?.address?.street) 
输出结果:Residence没有进行实例化操作nil 
从上可以看出,使用可空链式调用的好处,在于虽然endEvent.residencenil,在设置address属性时程序不会崩溃,只是设置会失败。 
四、通过可空链式调用来调用方法 
 
Residence类中,有一个printNumberOfRooms方法,是打印房子中房间数量的函数。对于这个函数,其返回值类型是Void。但是如果在可空值上,通过可空链式调用来调用此方法,返回值类型是Void?,而不是Void,因为通过可空链式调用得到的返回值是nil 
// 如果有实例操作,那么就会是调用成功,否则是调用失败//endEvent.residence = Residence() 
// 通过返回值是否为`nil`可以判断调用是否成功if endEvent.residence?.printNumberOfRooms() != nil { 
   print("调用成功") 
} else { 
   print("调用失败") 
} 
五、通过可空链式调用来访问下标 
 
通过可空链式调用,可以用下标来对可空值进行读写,并可以判断下标调用是否成功。 
注意当通过可空链式调用访问可空值的下标时,应该将问号放在下标方括号的前面而不是后面。可空链式调用的问号一般直接跟在可空表达式的后面。
endEvent.residence = Residence()// 追加操作 
endEvent.residence?.rooms.append(Room(name: "房间1")) 
endEvent.residence?.rooms.append(Room(name: "房间2")) 
endEvent.residence?.rooms.append(Room(name: "房间3"))// 通过可空链式调用来访问下标if let firstRoomName = endEvent.residence?[0].name { 
   print("第一个房间的名字是\(firstRoomName)") 
} else { 
   print("没有对应房间") 
} 
输出结果: 
第一个房间的名字:房间1 
// 访问可空类型的下标// 字典类型var dict = ["name":["张三","李四","王五"], 
           "age":[18, 20, 23]] 
// 用可空链式调用,把"name"数组第一个元素设置为"赵六" 
dict["name"]?[0] = "赵六" 
// "age"数组第一个元素设置为25 
dict["age"]?[0] = 25 
// "test"数组第一个元素设置为"测试",但是字典中不存在关键字为"test"的,所以这个是调用失败 
dict["test"]?[0] = "测试" 
print(dict) 
输出结果: 
["age": [25, 20, 23], "name": [赵六李四王五]] 
六、多层链接 
 
可以通过多个链接多个可空链式调用来向下访问属性、方法、下标。但是多层可空链式调用不会添加返回值的可空性,即是: 
如果访问的值不是可空的,通过可空链式调用将会可以放可空值。 
如果访问的值已经是可空的,通过可空链式调用不会变得""可空。 
// 多层可空链式调用let endEvent = Person()// 实例化Residence(如果没有下实例化,那么可空链式将会调用失败) 
endEvent.residence = Residence()// 实例化Addresslet guangzhou = Address() 
guangzhou.buildingName = "xxx" 
guangzhou.street = "广州 -- 体育中心" 
guangzhou.buildingTell = "xxx-xxx-xxx" 
endEvent.residence?.address = guangzhou 
// `street`属性是`String`endEvent.residence?.address?.street返回值是`String?`,即是已经进行了两次可空链式调用if let myStreet = endEvent.residence?.address?.street { 
   print("endEvent的住房地址: \(myStreet)") 
} else { 
   print("endEvent没有房子") 
} 
输出结果: 
endEvent的住房地址广州 -- 体育中心 
七、对返回可空值的函数进行链接 
 
除了通过可空链式调用获取可空属性值,也还可以通过可空链式调用来调用返回值为可空的方法。 
// 通过可空链式调用来调用`Address`中的`buildingIdentifier()`方法,返回类型是`String?` 
 if let myBuildingIdentifier = endEvent.residence?.address?.buildingIdentifier() { 
   print("建造信息: \(myBuildingIdentifier)") 
} 
注意在方法的括号后面加上问号,是因为buildingIdentifier()返回值是可空值,而不是方法本身是可空的!!! 
 
 
原文来自:简书EndEvent

如何学习Swift可空链式调用

标签:

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
jiangjie190
加入时间:2016-02-19
  关注此人  发短消息
文章分类
jiangjie190”关注的人------(0
jiangjie190”的粉丝们------(0
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!