寒城攻略:Listo 教你 25 天学会 Swift 语言 - 19 Optional Chaining

import Foundation


//***********************************************************************************************

//1.Optional Chaining(自判断链接)

//_______________________________________________________________________________________________

//介绍

//自判断链接是一种可以请求和调用属性,方法以及子脚本的过程,他的自判断性体现于请求或者调用的目标当前可能为空。如果自判断的目标有值,那么他的调用就会成功;如果目标为空,返回 nil


//***********************************************************************************************

//2.Optional Chaining as an Alternative to Forced Unwrapping(自判断链接可以替代强制拆包)

//_______________________________________________________________________________________________

//介绍

//通过在想调用属性,方法,或者子脚本的自判断值(非空)后放一个问号,可以定义一个自判断链接。


//_______________________________________________________________________________________________

//代码演示自判断链接和强制拆包的不同

class Person{               //Person 具有一个自判断 residence 属性

    var residence: Residence?

}

class Residence{            //Residence 具有一个 Int 类型的 numberOfRooms

    var numberOfRooms = 1

}


let john = Person()         //因为 Person 类中 residence 为自判断型,所以在创建实例的时候 residence 属性默认为空

//let roomCount = john.residence!.numberOfRooms       //如果我们此刻想要强制拆包的话,因为 john.residence nil,程序错误,只有当 john.residence 不为空的时候,程序才能运行


if let roomCount = john.residence?.numberOfRooms{           //使用自判断链接提供了另外一种方式去获取类实例属性,这时不会抱错,而是以 nil 的形式表示 john.residence

    println("john's residence has \(roomCount) room")

}

else{

    println("Unable to retrieve the number of rooms")

}


john.residence = Residence()            //自己定义一个 Residence 实例给 john.residence 这时它就不是空了

if let roomCount = john.residence?.numberOfRooms{

    println("john's residence has \(roomCount) room")

}

else{

    println("Unable to retrieve the number of rooms")

}


//***********************************************************************************************

//3.Defining Model Classes for Optional Chaining(为自判断链接定义模型类)

//_______________________________________________________________________________________________

//介绍

//我们可以使用自判断链接来多层调用属性,方法和子脚本

class Person1{

    var residence1: Residence1?

}


class Residence1{

    var rooms = [Room]()            //初始化 rooms 为一个空数组,存储的元素必须为 Room 类型

    var numberOfRooms: Int{

    return rooms.count

    }

    

    subscript(i: Int) -> Room{      //为了快速访问 rooms 数组, Residence1 定义了一个只读的子脚本,通过插入角标就可以成功调用

        return rooms[i]

    }

    

    func printNumberOfRooms(){      //打印房间个数

        println("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{

            return buildingName

        }

        else{

            return nil

        }

    }

}


//***********************************************************************************************

//4.Calling Properties Through Optional Chaining(通过自判断链接调用属性)

//_______________________________________________________________________________________________

//代码演示使用自判断链接替代强制拆包获取属性,并且检查属性是否获取成功

let john1 = Person1()

if let roomCount = john1.residence1?.numberOfRooms{         //由于 john1.residence1 nil,所以执行 else 中的语句

    println("john's residence has \(roomCount) rooms")

}

else{

    println("Unabel to retrieve the number of rooms")

}


//***********************************************************************************************

//5.Calling Methods Through Optional Chaining(通过自判断链接调用方法)

//_______________________________________________________________________________________________

//实例代码演示自判断链接调用方法

if john1.residence1?.printNumberOfRooms(){

    println("is was possible to print the number of rooms")

}

else{

    println("it was not possible to print the number of rooms")

}


//***********************************************************************************************

//6.Calling Subscripts Through Optional Chaining(通过自判断链接调用子脚本)

//_______________________________________________________________________________________________

//实例代码演示通过自判断链接调用子脚本

if let firstRoomName = john1.residence1?[0].name {

    println("The first room is \(firstRoomName)")

}

else{

    println("Unable to retrieve the first room name")

}


let Listo = Residence1()

Listo.rooms += Room(name: "Pin")

Listo.rooms += Room(name: "Melody")

john1.residence1 = Listo            // john1.residence1 创建实例


if let firstRoomName = john1.residence1?[0].name{

    println("the first room is \(firstRoomName)")

}

else{

    println("Unable to retrieve the first room name")

}


//***********************************************************************************************

//7.CLinking Multiple Levels of Chaining(连接多层链接)

//_______________________________________________________________________________________________

//代码演示连接多层链接

if let johnsStreet = john1.residence1?.address?.street{        //此时 john1.residence1 不是 nil,但 john1.residence1.address nil,所以返回 else 语句

    println("john's street name is \(johnsStreet)")

}

else{

    println("Unable to retrieve the address")

}


let address = Address()

address.buildingName = "The Larches"

address.street = "laurel Street"

john1.residence1!.address = address     // john1.residence1.address 赋值


if let johnsStreet = john1.residence1?.address?.street{        //此时 john1.residence1 不是 nil,但 john1.residence1.address nil,所以返回 else 语句

    println("john's street name is \(johnsStreet)")

}

else{

    println("Unable to retrieve the address")

}


//***********************************************************************************************

//8.Chaining on Methods With Optional Return Values(链接自判断返回值的方法)

//_______________________________________________________________________________________________

//代码实例演示自判断连接的返回值方法

if let buildingIdentifier = john1.residence1?.address?.buildingIdentifier(){

    println("john's building identifier is \(buildingIdentifier)")          //返回的值依旧是 String 类型的自判断链接

}


if let buildingIdentifier = john1.residence1?.address?.buildingIdentifier()?.uppercaseString{       //当继续对自判断链接执行操作室,使用 ?. 来间隔方法

    println("john's building identifier is \(buildingIdentifier)")          //返回的值依旧是 String 类型的自判断链接

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值