Swift2.0语言教程之类的嵌套与可选链接
Swift2.0语言教程之类的嵌套与可选链接
Swift2.0语言类的嵌套
在一个类中可以嵌套一个或者多个类。它们的嵌套形式也是不同的,大致分为了两种:直接嵌套和多次嵌套。下面依次讲解这两种方式。
Swift2.0语言的直接嵌套
当一个类或者多个类直接嵌套在另外一个类,这时就构成直接嵌套,如图8.6所示。

图8.6 类的嵌套
在图8.6中,类2、类3和类4都是直接嵌套在类1中。对于这种情况,使用类1的实例属性和方法,语法形式如下:
- 类1().属性
- 类1().方法
使用类1的类型属性和方法的形式如下:
- 类1.属性
- 类1.方法
使用类2的实例属性和方法,语法形式如下:
- 类1.类2().属性
- 类1.类2().方法
使用类2的类型属性和方法的形式如下:
- 类1.类2.属性
- 类1.类2.方法
类3和类4的使用方法类似。
【示例8-21】以下将定义一个直接嵌套的类NewClass,在此类中嵌套了Str1Class、Str2Class、Str3Class这3个类,和一个可以输出这3个类中属性内容的方法。在Str1Class、Str2Class、Str3Class这三个类中又定义了类型属性,它们都会返回一个字符串。代码如下:
- import Foundation
- class NewClass {
- class func printstr(str:String){
- print(str)
- }
- //Str1Class类
- class Str1Class{
- class var str:String{
- return "Swift"
- }
- }
- //Str2Class类
- class Str2Class{
- class var str:String{
- return "Hello"
- }
- }
- //Str3Class类
- class Str3Class{
- class var str:String{
- return "World"
- }
- }
- }
- //调用
- NewClass.printstr(NewClass.Str1Class.str)
- NewClass.printstr(NewClass.Str2Class.str)
- NewClass.printstr(NewClass.Str3Class.str)
在此代码中,在一个NewCllass类中有包含了3个类,分别为Str1Class、Str2Class、Str3Class。运行结果如下所示:
- Swift
- Hello
- World
Swift2.0语言的多次嵌套
Swift中,类的嵌套不仅允许一次嵌套,还允许多次嵌套。这时的嵌套形式如图8.7所示。

图8.7 类的嵌套2
类3和类4是直接嵌套在类2中,而类2又直接嵌套在类1。这样形成了多层嵌套。这时,如果访问类1的实例属性和方法,其语法形式如下:
- 类1().属性
- 类1().方法
访问类1的类型属性和方法,其语法形式如下:
- 类1.属性
- 类1.方法
如果要访问类2的实例属性和方法,对应的语法形式如下:
- 类1.类2().属性
- 类1.类2().方法
访问类2的类型属性和方法,对应的语法形式如下:
- 类1.类2.属性
- 类1.类2.方法
如果要访问类3的实例属性和方法,对应的语法形式如下:
- 类1.类2.类3().属性
- 类1.类2.类3().方法
如果要访问类3的类型属性和方法,对应的语法形式如下:
- 类1.类2.类3.属性
- 类1.类2.类3.方法
【示例8-22】以下将定义一个多次嵌套的类NewClass,在此类中嵌套了StrClass类,和一个可以输出属性内容的方法。在StrClass类中又嵌套了Str1Class、Str2Class、Str3Class这3个类,它们都会返回一个字符串。代码如下:
- import Foundation
- class NewClass {
- class func printstr(str:String){
- print(str)
- }
- // StrClass类
- class StrClass{
- // StrClass1类
- class Str1Class{
- class var str:String{
- return "Hello"
- }
- }
- // StrClass2类
- class Str2Class{
- class var str:String{
- return "Swift"
- }
- }
- // StrClass3类
- class Str3Class{
- class var str:String{
- return "World"
- }
- }
- }
- }
- //调用
- NewClass.printstr(NewClass.StrClass.Str1Class.str)
- NewClass.printstr(NewClass.StrClass.Str2Class.str)
- NewClass.printstr(NewClass.StrClass.Str3Class.str)
在此代码中,在一个NewCllass类中有包含了1个类StrClass,在StrClass类中又包含了3个类,分别为Str1Class、Str2Class、Str3Class。运行结果如下所示:
- Hello
- Swift
- World
Swift2.0语言的可选链接
在类或者其他的类型中,声明的属性和变量/常量,都不可以为空。为了解决这一问题,Swift提出了可选类型。通过可选类型定义的元素可以为空或者是不为空,但是如何要使用这些可选类型的值又成为一大难题。Swift接着就提出了可选链接。可选链接可以判断请求或调用的目标(属性、方法、下标脚本等)是否为空。如果目标有值,那么调用就会成功;相反,则返回空(nil)。对于多次请求或调用的可以被链接在一起形成一个链条。Swift中的可选链接和Objective-C中的消息为空类似,但是Swift可以使用在任意的类型中使用,并且失败与否可以被检测到。以下将详细讲解可选链接的内容。
Swift2.0语言的可选链接的实现方式
可选链接其实就是使用“?”问号操作符对可选类型实现的一种运算。开发者可以在想要调用的属性、下标脚本和方法的可选值后面添加一个“?”问号来进行可选链接的定义。以下就是对于这些可选链接的定义形式:
- 属性名? //属性的可选链接
- 下标脚本? //下标脚本的可选链接
- 方法名? //方法的可选链接
对象可选链接的调用形式如下:
- 对象名.可选链接
【示例8-23】以下将判断值是否存在,其代码如下:
- import Foundation
- class Residence {
- //定义一个可选类型的类型属性numberOfRooms
- class var numberOfRooms:Int?{
- return 100
- }
- var number:Int?
- }
- let newClass=Residence()
- if let a=Residence.numberOfRooms { //判断a是否有值
- print("目标有值")
- }else{
- print("目标为空")
- }
- if let a=newClass.number { //可选链接
- print("目标有值")
- }else{
- print("目标为空")
- }
在此代码中,由于umberOfRooms的属性值不为空,所以会出现"目标有值",但是对于number属性来说,没有赋初值即number属性为nil,所以会出现"目标为空"运行结果如下所示:
- 目标有值
- 目标为空
注意:在定属性、下标脚本以及方法定义为可选链接时,这些属性、下标脚本和方法都必须是可选类型,否则程序就会出现以下的错误。如以下的代码,是对属性进行的可选链接:
- import Foundation
- class NewClass{
- var value:Int=10
- }
- let newClass=NewClass()
- let newValue=newClass.value?
- print(newValue)
由于在此代码中对一个不是可选类型的属性进行了可选链接定义,导致程序出现了以下的错误:
- Operand of postfix '?' should have optional type; type is 'Int'
Swift2.0语言通过可选链接调用属性、下标脚本、方法
开发者可以使用可选链接的可选值来调用属性、下标脚本和方法,并检查这些内容调用是否成功。以下就是通过可选链接调用属性、下标脚本、方法的详细讲解。
1.通过可选链接调用属性
通过可选链接调用属性的语法形式如下:
- 可选链接.属性名
【示例8-24】以下将通过自判断可选链接来调用属性值,并获取这个属性值。代码如下:
- import Foundation
- class Person {
- var residence: Residence?
- }
- class Residence {
- var numberOfRooms = 10
- }
- let john = Person()
- if let roomCount = john.residence?.numberOfRooms { //通过可选链接调用属性
- print("John在房子中有 \(roomCount)个房间")
- } else {
- print("无法检索房间数")
- }
由于john.residence是空,所以这个可选链接就会失败,但是不会出现错误,会返回一个nil。运行结果如下:
- 无法检索房间数
如果不想返回nil l,开发者需要将john.residence设置为不为空。如以下的代码,将john.residence设置为johnResidence。代码如下:
- let john = Person()
- let johnResidence = Residence()
- john.residence=johnResidence
- if let roomCount = john.residence?.numberOfRooms { //通过可选链接调用属性
- print("John在房子中有 \(roomCount)个房间")
- } else {
- print("无法检索房间数")
- }
运行结果如下:
- John在房子中有 10个房间
2. 通过可选链接调用下标脚本
通过可选链接调用下标脚本的语法形式如下:
- 可选链接.[下标]
【示例8-25】以下将通过自判断可选链接来调用下标脚本。代码如下:
- import Foundation
- class Person {
- var residence: Residence?
- }
- class Residence {
- subscript(i: Int) -> Int {
- return i
- }
- }
- let john = Person()
- if let firstRoomName = john.residence?[5] { //通过可选链接调用下标脚本
- print("John在房子中有 \(firstRoomName)个房子")
- } else {
- print("无法检索房间数")
- }
运行结果如下所示:
- 无法检索房间数
注意:当开发者使用可选链来调用子脚本的时候,你应该将“?”问号放在下标脚本括号的前面而不是后面。可选链的问号一般直接跟在自判断表达语句的后面。否则程序就会出现错误。如以下的代码就将上面的代码做了一下修改,代码如下:
- let john = Person()
- if let firstRoomName = john.residence[5]? { //通过可选链接调用下标脚本
- print("John在房子中有 \(firstRoomName)个房子")
- } else {
- print("无法检索房间数")
- }
在此代码中就“?”问号放在了下标脚本括号得后面,导致程序出现了以下的错误:
- 'Residence?' does not have a member named 'subscript'
3.通过可选链接调用方法
通过可选链接调用方法的语法形式如下:
- 可选链接.方法
【示例8-26】以下将通过自判断可选链接来调用方法printNumberOfRooms(),此方法的功能是输出numberOfRooms的值。代码如下:
- import Foundation
- class Person {
- var residence: Residence?
- }
- class Residence {
- var numberOfRooms=10
- func printNumberOfRooms() {
- print("The number of rooms is \(numberOfRooms)")
- }
- }
- let john = Person()
- if let a: ()=john.residence?.printNumberOfRooms() { ////通过可选链接调用方法
- print("打印房间数")
- } else {
- print("无法打印房间数")
- }
运行结果如下:
- 无法打印房间数
Swift2.0语言中连接多个链接
开发者可以将多个可选链接放在一起,如以下的代码,此代码实现的功能是将获取属性street的内容。代码如下:
- import Foundation
- // Person类,定义了属性residence
- class Person {
- var residence: Residence?
- }
- // Residence类,定义了属性address
- class Residence {
- var address: Address?
- }
- // Address类定义了属性street
- class Address {
- var street: String?
- }
- //实例化对象
- let john = Person()
- let johnsHouse = Residence()
- john.residence = johnsHouse
- let johnsAddress = Address()
- //赋值
- johnsHouse.address=johnsAddress
- johnsAddress.street = "Laurel Street"
- if let johnsStreet = john.residence?.address?.street { //链接了两个可选链接
- print("John的地址为: \(johnsStreet)")
- } else {
- print("无法检索地址")
- }
在此代码中,john.residence现在存在一个实例johnsHouse,而不是nil,而john.residence?.address现在也存在一个实例johnsAddress,并为street设置了实例的值。所以在执行程序后,会返回Street的值。运行结果如下:
- John的地址为: Laurel Street
本文选自:Swift2.0语言快速入门v3.0 大学霸内部资料,转载请注明出处,尊重技术尊重IT人!
Swift2.0语言教程之类的嵌套与可选链接的更多相关文章
- Swift2.0语言教程之函数嵌套调用形式
Swift2.0语言教程之函数嵌套调用形式 Swift2.0语言函数嵌套调用形式 在Swift中,在函数中还能够调用函数,从而形成嵌套调用.嵌套调用的形式往往有两种:一种是在一个函数中调用其它函数:还 ...
- Swift2.0语言教程之下标脚本
Swift2.0语言教程之下标脚本 下标脚本 下标脚本是访问对象.集合或者序列的快速方式.开发者不需要调用实例特定的赋值和访问方法,就可以直接访问所需要的数值.例如在数组中,可以直接使用下标去访问或者 ...
- Swift2.0语言教程之类的方法
Swift2.0语言教程之类的方法 Swift2.0语言的方法 方法其实就是函数,只不过它被定义在了类中.在Swift中,根据被使用的方式不同,方法分为了实例方法和类型方法两种.这两种方法的定义也和O ...
- Swift2.0语言教程之类的属性
Swift2.0语言教程之类的属性 类 虽然函数可以简化代码,但是当一个程序中出现成百上千的函数和变量时,代码还是会显得很混乱.为此,人们又引入了新的类型——类.它是人们构建代码所用的一种通用.灵活的 ...
- Swift2.0语言教程之闭包
Swift2.0语言教程之闭包 Swift2.0语言闭包 闭包是自包含的函数代码块,可以在代码中被传递和使用.Swift中的闭包与C和Objective-C中的代码块(blocks)以及其他一些编程语 ...
- Swift2.0语言教程之函数的返回值与函数类型
Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...
- Swift3.0语言教程字符串与URL的数据转换与自由转换
Swift3.0语言教程字符串与URL的数据转换与自由转换 Swift3.0语言教程字符串与URL的数据转换 Swift3.0语言教程字符串与URL的数据转换与自由转换,字符串中的字符永久保存除了可以 ...
- Swift3.0语言教程字符串与文件的数据转换
Swift3.0语言教程字符串与文件的数据转换 Swift3.0语言教程字符串与文件的数据转换,如果想要对字符串中的字符进行永久保存,可以将字符串中的字符写入到文件中.当然,开发者也可以将写入的内容进 ...
- Swift3.0语言教程字符串转换为数字值
Swift3.0语言教程字符串转换为数字值 Swift3.0语言教程字符串转换为数字值,在NSString中,开发者可以将字符串转换为数字值,通过这些数字值可以实现一些功能,如加法运算.减法运算等.数 ...
随机推荐
- 【leetcode 简单】 第九十八题 第三大的数
给定一个非空数组,返回此数组中第三大的数.如果不存在,则返回数组中最大的数.要求算法时间复杂度必须是O(n). 示例 1: 输入: [3, 2, 1] 输出: 1 解释: 第三大的数是 1. 示例 2 ...
- PHP在Linux下Apache环境中执行exec,system,passthru等服务器命令函数
更多内容推荐微信公众号,欢迎关注: 若在服务器中使用php test.php运行exec,system,passthru等命令相关的脚本能成功运行,在web页面却没反应, [可能是服务器端,PHP脚本 ...
- 二维码扫描开源库ZXing定制化
最近在用ZXing这个开源库做二维码的扫描模块,开发过程的一些代码修改和裁剪的经验和大家分享一下. 建议: 如果需要集成到自己的app上,而不是做一个demo,不推荐用ZXing的Android外围开 ...
- 25 个常用的 Linux iptables 规则【转】
转自 25 个常用的 Linux iptables 规则 - 文章 - 伯乐在线http://blog.jobbole.com/108468/ # 1. 删除所有现有规则 iptables -F # ...
- HDU 6199 2017沈阳网络赛 DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6199 题意:n堆石子,Alice和Bob来做游戏,一个人选择取K堆那么另外一个人就必须取k堆或者k+1 ...
- 二十、springboot之jpa开发@MappedSuperclass 注解说明
@MappedSuperclass使用条件: 当我们进行开发项目时,我们经常会用到实体映射到数据库表的操作,此时我们经常会发现在我们需要映射的几个实体类中,有几个共同的属性,例如编号ID,创建者,创建 ...
- 基于RESTful API 设计用户权限控制
RESTful简述 本文是基于RESTful描述的,需要你对这个有初步的了解. RESTful是什么? Representational State Transfer,简称REST,是Roy Fiel ...
- 泛型 for to/in 遍历 PK 效率;TEnumerator、TEnumerable
再使用泛型的时候,经常需要用到遍历功能: 只要继承了 TEnumerator 或 TEnumerable 这两个抽象类的 都具有遍历功能. 当然没有继承这两个抽象类的 也具有使用 for in 来遍历 ...
- Springboot + Vue + shiro 实现前后端分离、权限控制
本文总结自实习中对项目对重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelA ...
- ROSCon 2017通知 Announcing ROSCon 2017: September 21st and 22nd in Vancouver
ROSCon 2017通知:9月21日和22日在温哥华 我们很高兴地宣布,2017年ROSCon将在举行9月21-22日,2017年温哥华会议中心在加拿大温哥华.2017年IROS将在同一地点9月24 ...