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.")
 }

链接具有可选返回值的方法

可选链接也用于访问定义方法的子类。

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")
 }
微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?