zoukankan      html  css  js  c++  java
  • Swift-09-可空链式调用(Optional Chaining)

      我对这个的理解就是:我们有可能会用到其他的属性或者方法,当我们在使用其他的时候,可以使用点语法去访问另一个的属性,这样的使用,就形成了链式访问。

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

      Attention:Swift的可空链式调用和OC中的消息为空有些相像,但是Swift可以使用在任意类型中,并且能够检查调用是否为空。

      ------如何定义为可空链呢?

      在属性、方法、下表的可空值后面放一个问号,可以定义一个可空链。这一点很像在可空值后面放一个叹号!来强制展开其中值。他们的区别是,当可空值为空时,可空链式只是调用失败,然而强制展开将会触发运行时错误。

      如果调用一个空对象的任何属性,将返回可空值,无论它的属性是不是可空值。可以通过返回值来判断你的可空链式调用是否调用成功,如果有返回值,则调用成功;如果返回nil则调用失败。

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

      可空类型长什么样子呢?示例如下:

    class Person {
        var residence :Residence? //这个问号表明了residence是一个可空的属性,它的类型为Residence?
    }

      如果新建一个Person实例,因为它的residence属性是可空的,john的属性将初始化为nil。

    let john = Person()
    let roomCount = john.residence!.numberOfRooms
    报错信息:fatal error: unexpectedly found nil while unwrapping an Optional value
    

      当使用叹号!强制展开获得这个john的residence属性中的numberOfRooms值,会触发运行时错误,因为没有可以展开的residence。。

      

    class Person {
        var residence :Residence?
    }
    
    class Residence {
        var numberOfRooms = 1
    }
    
    let john = Person()
    let res:Residence = Residence()
    let roomCount = john.residence?.numberOfRooms
    print(roomCount)
    

      print:nil

      因为访问numberOfRooms有可能失败,可空链式调用会返回Int?类型,或者称为“可空的Int”。当实例为nil,将返回nil。

      当给person的residence赋值后,就可以用返回值了:

    let john = Person()
    john.residence = Residence()
    let roomCount = john.residence?.numberOfRooms
    print(roomCount)
    
    打印结果:Optional(1)
    

      ****为可空链式调用定义模型类

      通过使用可空链式调用可以调用多层属性,方法,和下标。这样就可以通过各种模型向下访问各种子属性,并且判断能否访问子属性的属性、方法或下标。

      -----通过可空链式调用来访问下标

      可以通过下标来对可空值进行读取或写入,并且判断下标调用是否成功。当通过可空链式调用访问可空值的下标的时候,应该将问号放在下标方括号的前面,可空链式调用的问号一般直接跟在可空表达式的后面。

    john.residence?[0] = Room(name: "Bathroom") 
    let johsnHouse = Residence()
    johsnHouse.rooms.append(Room(name: "Living Room"))
    johsnHouse.rooms.append(Room(name: "Kitchen"))
    john.residence = johsnHouse
    
    if let roomCount = john.residence?.numberOfRooms{
        print(roomCount)
    }else{
        print("ni;")
    }
    if let firstRoomName = john.residence?[0].name
    {
        print(firstRoomName)
    }else{
        print("meiyou")
    }
    
    运行结果:
    2
    Living Room
    

      -----访问可空类型的下标

      如果下标返回可空类型值,比如在Swift中Dictionary的key下标,可以在下标的闭合括号后面放一个问号来链接下标的可空返回值。

    var testScores = ["Bev":[79,94,81],"Dave":[86,82,84]]
    testScores["Dave"]?[0] = 91
    testScores["Bev"]?[0]++
    testScores["Brian"]?[0] = 72--->调用失败
    print(testScores)
    打印:
    ["Bev": [80, 94, 81], "Dave": [91, 82, 84]]
    

      -----多层链接

      可以通过链接多个可空链式调用来向下访问属性、方法及下标。但是多层可空链式调用不会添加返回值的可空性。

      1.如果你访问的值不是可空的,通过可空链式调用将会返回可空值;

      2.如果你访问的值已经是可空的,通过可空链式调用不会变的“更”可空;

    if let johnStreet = john.residence?.address?.street
    {
        print(johnStreet)
    }else{
        print("not street")
    }
    
    let someAddress = Address()
    someAddress.buildingNumber = "The 29"
    someAddress.buildingName = "The ABC"
    john.residence?.address = someAddress
    
    if let beginsWith = john.residence?.address?.buildingIdentifier()?.hasPrefix("The"){
        if beginsWith{
            print("the beig")
        }else{
            print("not the")
        }
    }else{
        print(john.residence?.address?.buildingIdentifier())
    }
    

      在方法的圆括号后面加上问号,是因为buildIdentifier()的返回值是可空值,而不是方法本身是可空的。

      

  • 相关阅读:
    android activity lifecycle
    android hal 分析
    android hardware.c 源码分析
    linux cpio
    android boot.img unpack pack
    imx6 android4.2 编译
    repo 安装
    repo manifest.xml 分析
    ElasticSearch 5.0.0 安装部署常见错误或问题
    elasticsearch 安装(基于java运行环境)
  • 原文地址:https://www.cnblogs.com/tanglimei/p/5142202.html
Copyright © 2011-2022 走看看