swift可选链式调用 – Swift最新教程

上一章Swift教程请查看:swift析构过程和自动引用计数(ARC)
在一个可能是“nil”的可选对象上查询、调用属性、下标和方法的过程被定义为可选链接,可选的链接返回两个值:

  • 如果可选包含一个“值”,那么调用它的相关属性、方法和下标将返回值
  • 如果可选项包含一个“nil”值,那么它的所有相关属性、方法和下标都将返回nil
由于对方法的多个查询,属性和下标被分组在一起,一个链的失败将影响整个链并导致’ nil’ 值。
可选的链接作为强制展开的替代方法可选链接是在‘?在可选值返回某些值时调用属性、方法或下标。
可选的链接“?” 访问方法,属性和订阅可选链接’ !强迫拆开包装
?放置在可选值之后以调用属性、方法或下标 !是否放置在可选值之后以调用属性、方法或下标以强制展开值
当可选项为“nil”时,会优雅地失败 当可选参数为“nil”时,强制展开将触发运行时错误。
可选链接和’ !’ 的程序
class ElectionPoll { var candidate: Pollbooth? } lass Pollbooth { var name = "MP" } let cand = ElectionPoll() let candname = cand.candidate!.name

上面的程序声明’ election poll’ 作为类名,并包含’ candidate’ 作为成员函数。子类声明为’ poll booth’ , ‘ name’ 作为其成员函数,初始化为’ MP’ 。对超类的调用是通过创建一个实例’ cand’ 和一个可选的’ !’ 来初始化的。由于值没有在基类中声明,因此“nil”值被存储,从而通过强制展开过程返回一个致命错误。
可选链接与’ ?’ 的程序
class ElectionPoll { var candidate: Pollbooth? } class Pollbooth { var name = "MP" } let cand = ElectionPoll() if let candname = cand.candidate?.name { print("name \(candname)") } else { print("无法返回") }

上面的程序声明’ election poll’ 作为类名,并包含’ candidate’ 作为成员函数。子类声明为’ poll booth’ , ‘ name’ 作为其成员函数,初始化为’ MP’ 。对超类的调用是通过创建一个实例’ cand’ 和一个可选的’ ?’ 来初始化的。因为这些值没有在基类中声明,所以‘nil’值由else处理程序块存储并打印在控制台中。
为可选的链接和访问属性定义模型类Swift 语言还提供了可选链接的概念,将多个子类声明为模型类。这个概念对于定义复杂模型和访问属性、方法和下标子属性非常有用。
class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print("The number of rooms is \(cprint)") } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var street: String? func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let rectname = rectangle() if let rectarea = rectname.print?.cprint { print("Area: \(rectarea)") } else { print("not specified ") }

通过可选链接调用方法
class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print("Area: \(cprint)") } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var circumarea: String?func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let circname = rectangle() if circname.print?.circleprint() != nil { print("is specified)") } else { print("not specified") }

通过创建一个名为“circname”的实例来调用circle()子类中声明的函数circleprint()。该函数将返回一个值,如果它包含一些值,否则它将返回一些用户定义的打印消息,通过检查语句’ if circname.print?.circleprint() != nil’ 。
通过可选链接访问下标可选链接用于设置和检索下标值,以验证调用该下标是否返回值。”?’ 放在下标大括号前,以访问特定下标上的可选值。
class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print("number: \(cprint)") } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname =radiusname } } class circumference { var circumName: String? var circumNumber: String? var circumarea: String?func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let circname = rectangle() if let radiusName = circname.print?[0].radiusname { print("name: \(radiusName).") } else { print("not specified.") }

在上面的程序中,没有指定成员函数’ radiusName’ 的实例值。因此,对函数的程序调用将只返回else部分,而要返回值,我们必须为特定的成员函数定义值。
访问可选类型的下标
class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print("number: \(cprint)") } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var circumarea: String?func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let circname = rectangle() circname.print?[0] = radius(radiusname: "Diameter") let printing = circle() printing.area.append(radius(radiusname: "Units")) printing.area.append(radius(radiusname: "Meter")) circname.print = printing var area = ["Radius": [35, 45, 78, 101], "Circle": [90, 45, 56]] area["Radius"]?[1] = 78 area["Circle"]?[1]-- print(area["Radius"]?[0]) print(area["Radius"]?[1]) print(area["Radius"]?[2]) print(area["Radius"]?[3]) print(area["Circle"]?[0]) print(area["Circle"]?[1]) print(area["Circle"]?[2])

下标的可选值可以通过引用它们的下标值来访问。可用下标[0]、下标[1]等方式访问。’ radius’ 的默认下标值首先被赋值为[35,45,78,101],而’ Circle'[90, 45, 56]]。然后将下标值更改为半径[0]为78,圆[1]为45。
链接多级链接多个子类还可以通过可选链接与其超类方法、属性和下标链接在一起。
可选的多重链接可以是链接的
如果检索类型不是可选的,可选链接将返回一个可选值。例如,如果字符串通过可选链接,它将返回String?Value。
class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print("number: \(cprint)") } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var circumarea: String? func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let circname = rectangle() if let radiusName = circname.print?[0].radiusname { print("name: \(radiusName).") } else { print("not specified.") }

链接具有可选返回值的方法【swift可选链式调用 – Swift最新教程】可选链接也用于访问定义方法的子类。
class rectangle { var print: circle? } class circle { var area = [radius]() var cprint: Int { return area.count } subscript(i: Int) -> radius { get { return area[i] } set { area[i] = newValue } } func circleprint() { print("Area: \(cprint)") } var rectarea: circumference? } class radius { let radiusname: String init(radiusname: String) { self.radiusname = radiusname } } class circumference { var circumName: String? var circumNumber: String? var circumarea: String?func buildingIdentifier() -> String? { if circumName != nil { return circumName } else if circumNumber != nil { return circumNumber } else { return nil } } } let circname = rectangle() if circname.print?.circleprint() != nil { print("is specified)") } else { print("not specified") }

    推荐阅读