深入解析Swift语言编程中的可选链

 更新时间:2015年11月07日 15:01:48   投稿:goldensun  
这篇文章主要介绍了深入解析Swift语言编程中的可选链,是Swift入门学习中的基础知识,需要的朋友可以参考下

查询,调用属性,下标和方法上的一个可选可能 'nil' 的过程被定义为可选的链。可选链返回两个值

如果可选包含一个值,然后调用其相关属性,方法和下标返回值

如果可选包含一个“nil”值,所有的相关属性,方法和下标返回nil

由于多种查询方法,属性和下标故障组合在一起,以一种链将影响到整个链,并导致产生 'nil' 的值。

可选链作为一种替代强制解包裹
可选链与可选值后指定“?”调用一个属性,方法或下标当可选的值返回一些值。

2015117145605093.png (718×113)

程序用于可选链 '!'

复制代码 代码如下:

class ElectionPoll {
   var candidate: Pollbooth?
}
class Pollbooth {  
   var name = "MP"
}
 
let cand = ElectionPoll()
  
let candname = cand.candidate!.name

当我们使用 playground 运行上面的程序,得到以下结果。

fatal error: unexpectedly found nil while unwrapping an Optional value
0 swift   0x0000000103410b68 llvm::sys::PrintStackTrace(__sFILE*) + 40
1 swift   0x0000000103411054 SignalHandler(int) + 452
2 libsystem_platform.dylib 0x00007fff9176af1a _sigtramp + 26
3 libsystem_platform.dylib 0x000000000000000b _sigtramp + 1854492939
4 libsystem_platform.dylib 0x00000001074a0214 _sigtramp + 1976783636
5 swift   0x0000000102a85c39 llvm::JIT::runFunction(llvm::Function*, std::__1::vector > const&) + 329
6 swift   0x0000000102d320b3 llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, char const* const*) + 1523
7 swift   0x000000010296e6ba swift::RunImmediately(swift::CompilerInstance&, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, swift::IRGenOptions&, swift::SILOptions const&) + 1066
8 swift   0x000000010275764b frontend_main(llvm::ArrayRef, char const*, void*) + 5275
9 swift   0x0000000102754a6d main + 1677
10 libdyld.dylib  0x00007fff8bb9e5c9 start + 1
11 libdyld.dylib  0x000000000000000c start + 1950751300
Stack dump:
0. Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret - -target x86_64-apple-darwin14.0.0 -target-cpu core2 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -module-name main 
/bin/sh: line 47: 15672 Done   cat <<'SWIFT'
import Foundation

上述程序中声明“ 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 {
   println("Candidate name is \(candname)")
}
else {
   println("Candidate name cannot be retreived")
}

当我们使用 playground 运行上面的程序,得到以下结果。

Candidate name cannot be retreived

上述程序中声明“ election poll” 作为类名,并包含了作为隶属函数“candidate”。子类被声明为 “poll booth” 和 “name” 作为被初始化为 'MP' 的隶属度函数。对超类的调用是通过创建一个实例,“cand”可选的初始化“?”。由于基类 'nil' 的值不声明被存储并打印在控制台,由其他程序块处理。

定义模型类的可选链接和访问属性
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() {
      println("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 {
   println("Area of rectangle is \(rectarea)")
}  else {
   println("Rectangle Area is not specified")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Rectangle Area is 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() {
      println("Area of Circle 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 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 {
   println("Area of circle is specified)")
} else {
   println("Area of circle is not specified")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Area of circle is not specified

该函数circleprint()在circle()子类中声明通过创建名为 “circname” 的一个实例来调用。函数会返回一个值 如果它包含一定的值则返回一些用户定义的打印信息。否则会被检查的语句 'if circname.print?.circleprint() != nil“

下标访问通过可选链
可选链设置和检索下标值以验证是否要调用该下标返回一个值。 '?' 被放置在下标括号之前来访问特定的标可选值。

程序 1

复制代码 代码如下:

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() {
      println("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 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 {
   println("The first room name is \(radiusName).")
} else {
   println("Radius is not specified.")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Radius is not specified.

在以上程序未指定成员函数 “radiusName” 的实例值。因此,程序调用该函数将返回唯一内容,以返回必须定义特定成员函数值的一部分。

程序 2

复制代码 代码如下:

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() {
      println("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 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

if let radiusName = circname.print?[0].radiusname {
   println("Radius is measured in \(radiusName).")
} else {
   println("Radius is not specified.")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Radius is measured in Units.

在上面的程序被指定为成员函数 “radiusName” 的实例值。 因此,程序现在调用函数将有返回值。

可选类型访问下标

复制代码 代码如下:

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() {
      println("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 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]--

println(area["Radius"]?[0])
println(area["Radius"]?[1])
println(area["Radius"]?[2])
println(area["Radius"]?[3])


println(area["Circle"]?[0])
println(area["Circle"]?[1])
println(area["Circle"]?[2])


当我们使用 playground 运行上面的程序,得到以下结果。

Optional(35)
Optional(78)
Optional(78)
Optional(101)
Optional(90)
Optional(44)
Optional(56)

对于下标可选的值可以通过参考其下标值来访问。它可访问为 subscript[0], subscript[1]等。radius 的默认值下标首先被指定为 [35,45,78,101] 和 Circle[90,45,56]。然后,下标值作为 Radius[0] 至78,以及Circle[1]〜45。

链接链的多层次性
多个子类也可以凭借其超类的方法,属性和下标通过可选链接联系。

可选的多个链可以链接:

如果检索类型是不可选的,可选链会返回一个可选值。例如,如果字符串通过可选链就会返回字符串?值

复制代码 代码如下:

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() {
      println("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 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 {
   println("The first room name is \(radiusName).")
} else {
   println("Radius is not specified.")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Radius is not specified.

在以上程序未指定隶属函数 “radiusName” 的实例值。 因此,程序调用该函数将返回唯一内容,我们必须定义返回值的特定隶属作为函数值的一部分。

如果检索式已经是可选的,那么可选链也将返回一个可选值。例如,如果字符串 ? 通过可选的链也将访问返回字符串 ?值。

复制代码 代码如下:

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() {
      println("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 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 {
   println("The first room name is \(radiusName).")
} else {
   println("Radius is not specified.")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Radius is measured in Units.

在上面的程序被指定为隶属函数 “radiusName” 的实例值。因此,程序调用函数将返回值。

链上的方法可选返回值
可选链是用来定义方法来访问子类。

复制代码 代码如下:

 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() {
      println("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 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

if let radiusName = circname.print?[0].radiusname {
   println("Radius is measured in \(radiusName).")
} else {
   println("Radius is not specified.")
}


当我们使用 playground 运行上面的程序,得到以下结果。

Area of circle is not specified

相关文章

  • 窥探Swift编程中的错误处理与异常抛出

    窥探Swift编程中的错误处理与异常抛出

    本文给大家整理些关于Swift编程中的错误处理与异常抛出,本文介绍的非常详细,基于参考价值,特此分享脚本之家平台供大家学习
    2016-02-02
  • 深入理解Swift中的访问控制关键字

    深入理解Swift中的访问控制关键字

    这篇文章主要给大家介绍了Swift中访问控制关键字的相关资料,文中介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • 详解Swift编程中的常量和变量

    详解Swift编程中的常量和变量

    这篇文章主要介绍了Swift编程中的常量和变量,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • Swift 3.0基础学习之闭包

    Swift 3.0基础学习之闭包

    Swift引进了闭包的概念,这个与object-c的block类似,使用过block的话都知道有多方便,所以开始学Swift,先要把闭包学会,后面使用会很频繁。下面这篇文章主要介绍了Swift 3.0基础学习之闭包的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-03-03
  • 深入解析Swift语言中的协议

    深入解析Swift语言中的协议

    这篇文章主要介绍了深入解析Swift语言中的协议,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • Swift开发之UITableView状态切换效果

    Swift开发之UITableView状态切换效果

    这篇文章主要介绍了Swift开发之UITableView状态切换效果的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • Swift仿选择电影票的效果并实现无限/自动轮播的方法

    Swift仿选择电影票的效果并实现无限/自动轮播的方法

    这篇文章主要给大家介绍了关于Swift仿选择电影票的效果并实现无限/自动轮播的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • Swift 4.0中如何引用3.0的第三方库

    Swift 4.0中如何引用3.0的第三方库

    这篇文章主要给大家介绍了关于在Swift 4.0中如何引用3.0第三方库的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • Swift可选值优化示例详解

    Swift可选值优化示例详解

    这篇文章主要为大家介绍了Swift可选值优化示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 在Mac OS的终端中运行Swift应用的方法

    在Mac OS的终端中运行Swift应用的方法

    这篇文章主要介绍了在Mac OS的终端中运行Swift应用的方法,依靠Xcode的REPL功能来实现,需要的朋友可以参考下
    2015-07-07

最新评论