17.可选链

摘要:
letroomCount=john.residence;String){self.name=name;}set{rooms[i]=newValue:}}funcprintNumberOfRooms(){print(“房间数(房间数)”);String;letsomeAddress=Address();//因为john.cept为nil;

  可选链式调用是一种可以在当前值可能为nil的可选值上请求和调用属性、方法及下标的方法。如果可选值有值,那么调用就会成功;如果可选值是nil,那么调用将返回nil。多个调用可以连接在一起形成一个调用链,如果其中任何一个节点为nil,整个调用链都会失败,即返回nil

  Swift 的可选链式调用和 Objective-C 中向nil发送消息有些相像,但是 Swift 的可选链式调用可以应用于任意类型,并且能检查调用是否成功。

1.使用可选链式调用代替强制展开

  • 通过在想调用的属性、方法、或下标的可选值(optional value)后面放一个问号(?),可以定义一个可选链。这一点很像在可选值后面放一个叹号(!)来强制展开它的值。它们的主要区别在于当可选值为空时可选链式调用只会调用失败,然而强制展开将会触发运行时错误。
  • 可选链式调用的返回结果与原本的返回结果具有相同的类型,但是被包装成了一个可选值。
class Person
{
    var residence: Residence?;
}

class Residence
{
    var numberOfRooms = 1;
}

let john = Person();
let roomCount = john.residence?.numberOfRooms;  //nil
//john.residence!.numberOfRooms;  //fatal error: unexpectedly found nil while unwrapping an Optional value

2.可选链式调用示例

  • 通过使用可选链式调用可以调用多层属性、方法和下标。这样可以在复杂的模型中向下访问各种子属性,并且判断能否访问子属性的属性、方法或下标。
class Person
{
    var residence: Residence?;
}

class Room
{
    let name: String;
    
    init(name: String)
    {
        self.name = name;
    }
}

class Residence
{
    var rooms = [Room]();
    var address: Address?;
    
    var numberOfRooms: Int
    {
        return rooms.count;
    }
    
    subscript(i: Int) -> Room {
        get
        {
            return rooms[i];
        }
        set
        {
            rooms[i] = newValue;
        }
    }
    
    func printNumberOfRooms()
    {
        print("The number of rooms is (numberOfRooms)");
    }
}

class Address
{
    var buildingName: String?;
    var buildingNumber: String?;
    var street: String?;
    
    func buildingIdentifier() -> String?
    {
        if buildingName != nil
        {
            return buildingName;
        }
        else if buildingNumber != nil && street != nil
        {
            return "(buildingNumber) (street)";
        }
        else
        {
            return nil;
        }
    }
}

//通过可选链式调用访问属性
let john = Person();
let someAddress = Address();
//因为john.residence为nil,所以这个可选链式调用会失败
john.residence?.address = someAddress;  //nil

//通过可选链式调用方法
let john1 = Person();
john1.residence?.printNumberOfRooms();  //不会调用方法
john1.residence = Residence();
john1.residence?.printNumberOfRooms();  //会调用方法
//连接多层可选链式调用
let beginsWithThe = john1.residence?.address?.buildingIdentifier()?.hasPrefix("The");  //nil

//通过可选链式调用访问下标
let john3 = Person();
john3.residence?[0] = Room(name: "Bathroom");  //nil

  【说明】:可以通过连接多个可选链式调用在更深的模型层级中访问属性、方法以及下标。然而,多层可选链式调用不会增加返回值的可选层级。

  • 通过可选链式调用访问一个Int值,将会返回Int?,无论使用了多少层可选链式调用。
  • 类似的,通过可选链式调用访问Int?值,依旧会返回Int?值,并不会返回Int??

 

免责声明:文章转载自《17.可选链》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇可能是一份没什么用的爬虫代理IP指南一个简单的webservice的demo(下)winform异步调用webservice下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python之(22)基础总结(5)

1、Python3 面向对象 1.面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 方法:类中定义的函数。 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 数据成员:类变量或者实例变量用于处理类及...

IE8+兼容经验小结

最近一段时间,我都使用Flask+Bootstrap3的框架组合进行开发。本文就是在这种技术组合下,分享IE8+兼容性问题的解决方法。根据我的实践经验,如果你在写HTML/CSS时候是按照W3C推荐的方式写的,然后下面的几点都关注过,那么基本上很大一部分IE8+兼容性问题都OK了(这里的IE8+主要是指IE8,据个人目测,IE9+的渲染效果已经非常好了)。...

使用Roslyn脚本化C#代码,C#动态脚本实现方案

【前言】   Roslyn 是微软公司开源的 .NET 编译器。   编译器支持 C# 和 Visual Basic 代码编译,并提供丰富的代码分析 API。   Roslyn不仅仅可以直接编译输出,难能可贵的就是上述描述中的开放了编译的API,使得代码脚本化成为了可能。   关于Roslyn,本文不做过多介绍,因为再介绍的丰满终究不及官方文档介绍的细腻,...

Unity3D面试题总结

一.什么是渲染管道? 是指在显示器上为了显示出图像而经过的一系列必要操作。 渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。 主要步骤有: 本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化。 二.如何优化内存? 有很多种方式,例如 1.压缩自带类库; 2.将...

解决cocos2dx在VS2012中文版环境下不支持中文的问题

  首先要明确的一点是:cocos2dx是支持中文的。因为其编码格式为UTF-8(无签名)——这只是我在网上找到的结论,并非从官方获取,因此不能十分确定,不过应该无误。   那么,为什么在VS2012环境下,cocos2dx不能正确显示中文呢?   这是因为二者编码格式不一致。VS2012中文版的默认编码格式为GB2312-80(我不确定英文版的格式如何,...

Java开发命名规范总结

类命名规范: 类名使用 UpperCamelCase 风格(首字母都大写),必须遵从驼峰形式。 例如: MessageUtil 抽象类命名使用 Abstract 或 Base 开头 ; 异常类命名使用 Exception 结尾 ; 测试类命名以它要测试的类的名称开始,以 Test 结尾。 对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来...