Swift中的链式调用

栏目: Swift · 发布时间: 3个月前

来源: juejin.im

本文转载自:https://juejin.im/post/5d07335451882563194b2d2d,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有。

每个写过 swift 的人都知道可选型的概念。一个可选型代表着它有两种可能性:它可能有一个值,通过解包这个可选型你能访问这个值;或者它不是一个值。可以使用!来强制解包。但是如果这个可选型为空的会触发运行时错误。所以如果你不想要运行时错误的话,有没有其他的选择可以优雅的处理为空的情况?答案当然是有,一个众所周知的选择就是可选型的链式调用。

在下面的篇幅里,我会让你熟悉可选型链式调用的多种用法,所以还在等什么呢?我们马上开始吧!

什么是可选型的链式调用

在我们了解可选型的链式调用的用法之前,让我先了解一下这是什么东西。可选型链式调用一个查询和调用当前可能为nil的可选型的属性、方法和下标的过程。我们都知道可选型有两种可能性。这就是为什么属性、方法和下标调用可选型时,如果有值就调用成功,如果没有则返回nil。它被称为链式调用,因为多个查询可以链接在一起,如果此链中的任何一个环节为nil,则整个链优雅地失败。

链式调用和强制解包的区别

我们都知道在可选型后面加上!可以强制解包,类似的在后面加一个问号的话,就表示如果不为空就访问属性、方法或者下标。即使访问的属性、方法或者下不是一个可选值,最后返回的结果也是一个可选值。比方说在调用时,一个本来返回String类型的方法会返回String?为了理解这这两者的区别,我们来看你个片段。

受限我们来定义两个类

class Student {
var degree: Course?
}

class Course {
var courseTitle = "B.Tech"
}
复制代码

现在,如果你创建一个Student实例,它的degree属性会默认初始化为空,因为它是一个可选型。所以在下面的代码里,nidhi有一个degree的属性,值为nil

let nidhi = Student()
let courseName = nidhi.degree!.courseTitle
    // this triggers a runtime error
复制代码

在这种情况下,如果你尝试用!来访问Student的degree属性,将会触发runtime错误,因为没有值去解包。现在我们来看可选型的链式调用

if let courseName = nidhi.degree?.courseTitle {
  print("Nidhi is pursuing \(courseName).")
} 
else {
  print("Unable to retrieve course name.")
}
复制代码

使用可选型的链式调用,如果可选型有值的话,后面的代码会被执行,如果是nil就断开,只执行部分代码。注意尽管course是一个非可选型的String,但由于它在链中被访问,所以它会返回String?而不是一个String。现在让我们将Course实例分配给nidhi.degree,使其不再包含nil值。

nidhi.degree = courseTitle()现在如果你链式访问courseTitle,它会返回包含值 “B.Tech”的String? 所以最后输出会是“Nidhi is persuing B.Tech.”

用于可选型链式访问的Swift模型类

可选型链式调用的一个重要用途是它允许我们在复杂类中声明一个可选项,我们可以在其中调用任何变量或常量属性,方法等。这种灵活性使我们可以深入研究相互关联类型的复杂模型中的子属性,还可以检查我们是否可以访问这些子属性的属性,方法和下标。让我们通过以下示例更好地理解这一点。在这个例子中,我们将声明两个类,其中一个类是复杂类(College),另一个类(Student)是访问其可选值。

class Student {
  var clg: College?
}

class College {
  var classes =  [ClassRoom]()
  var noOfClasses: Int {
    return classes.count
  }
  subscript (i: Int) -> ClassRoom {
    get  {
      return classes[i]
    }
    set  {
      return classes[i] = newValue
    }
  }
  func printNoOfClasses() {
    print("Number of Classes: \(noOfClasses)")
  }
  var address: Address?
}

class ClassRoom {
  var className: String
  init(className: String) { self.className = className }
}

class Address {
  var city: String?
  var area: String?
  func contactAdd() -> String? {
    if city != nil  {
        return city
    } else if area != nil {
        return area
    } else {
        return nil
    }
  }
}
let john = Student()
if let classCount =  john.clg?.noOfClasses {
  print("College has a \(classCount) Classes")
}
else {
  print("Unable to Retrieve No. of Classes")
}
复制代码

这里,类College存储一组ClassRoom实例,其noOfClasses属性实现为计算属性。计算属性noOfClasses只返回classes数组中count属性的值。作为访问其classes数组的快捷方式,这个类College提供了一个读写下标,可以在classes数组中的请求索引处提供对类课堂的访问。 Class College还提供了一种名为printNoOfClasses的方法,它只是打印了大学课堂的数量。最后,College定义了一个名为address的可选属性,其类型为Address类。用于classes数组的ClassRoom类是一个简单的类,它有一个名为className的属性,以及一个初始化程序,用于将该属性设置为合适的类房间名称。

当我们在操场上运行上面的代码时,我们将得到一个结果,“无法检索数量的类”,因为john.clg为零。

通过链式调用访问属性

可选链接可用于访问可选值的属性。我们还通过可选链接了解该属性访问是否成功。正如我们在上面的例子中看到的,当我们尝试访问noOfClasses时,链接失败,因为john.clg是nil。现在让我们看看如果我们尝试通过以下示例通过可选链接设置属性值会发生什么。

let clgAddress = Address()
    clgAddress.city = "Bangalore"
    clgddress.area = "Shivajinagar"
    john.clg?.address = clgAddress
复制代码

在此示例中,尝试设置john.clg的address属性将失败,因为john.clg当前为nil。

通过链式调用调用方法

我们可以使用可选链接在可选值上调用方法,以及检查该方法调用是否成功。即使该方法没有返回任何值,这也是可能的。不返回任何值的方法返回void,即返回值()或空元组。如果在可选链接上调用此方法,它将返回void?因为可选链接的结果总是可选的。例如,我们可以使用if语句检查是否可以调用printNoOfClasses()方法,即使该方法没有定义任何返回值。我们知道通过可选链接调用此方法将成功返回可选值,我们可以将printNoOfClasses()调用的返回值与nil进行比较,以了解方法调用是否成功。让我们看看演示这个的代码片段。

if john.clg?.printNoOfClasses() != nil {
    print("It was possible to print the number of classes.")
} else {
    print("It was not possible to print the number of classes.")
}
// Prints "It was not possible to print the number of classes."
复制代码

通过链式调用访问下标

除了调用方法和访问属性之外,还可以使用可选链接来尝试从可选值的下标中检索和设置值,并检查该下标调用是否成功。这可以通过以下示例以更好的方式解释。

if let firstClassName = john.clg?[0].className {
  print("The first class name is \(firstClassName).")
   } else {
        print("Unable to retrieve the first class name.")
    }
    // Prints "Unable to retrieve the first class name."
复制代码

john.clg目前为零,因此下标调用失败。

即使我们尝试通过带有可选链接的下标来设置新值

john.clg?[0] = Room(name: “Classroom-1”)

由于clg目前为零,因此该下标设置尝试也会失败。

如果我们创建并将实际的College实例分配给john.clg,并且在其classes数组中有一个或多个ClassRoom实例,我们可以使用可选链接来访问classes数组中的实际项。

访问可选类型的下标

如果下标返回一个可选的值,例如,Swift中字典类型的键下标,则可以修改使用可选类型声明的数组或字典的值。要在其可选的返回值上链接下标,请在下标的右括号后面添加一个问号。要理解这一点,请查看以下代码段。

连接多级链式调用

关于链接多级可选链接的一个有趣事实是,我们可以添加许多级别来深入查看属性,方法或下标,但是多级可选链接不会为返回值添加更多级别的可选性。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

关注码农网公众号

关注我们,获取更多IT资讯^_^


为你推荐:

相关软件推荐:

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

嵌入式系统软件设计中的常用算法

嵌入式系统软件设计中的常用算法

周航慈 / 2010-1 / 24.00元

《嵌入式系统软件设计中的常用算法》根据嵌入式系统软件设计需要的常用算法知识编写而成。基本内容有:线性方程组求解、代数插值和曲线拟合、数值积分、能谱处理、数字滤波、数理统计、自动控制、数据排序、数据压缩和检错纠错等常用算法。从嵌入式系统的实际应用出发,用通俗易懂的语言代替枯燥难懂的数学推导,使读者能在比较轻松的条件下学到最基本的常用算法,并为继续学习其他算法打下基础。 《嵌入式系统软件设计中的......一起来看看 《嵌入式系统软件设计中的常用算法》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具