一、Optional类型的概念

Swift中为何要引入Optional的概念,官方文档中有介绍:

Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Using optionals is similar to using

nil with pointers in Objective-C, but they work for any type, not just classes. Not only are optionals safer and more expressive than

nil pointers in Objective-C, they’re at the heart of many of Swift’s most powerful features.

总结下来就是:可选类型用来表示“有一个值,它等于x或者根本没有值”。当我们遇到Optional类型时,就会明显知道这里的值可能为nil,我们必须谨慎处理。这样的做法要比Objective-C更加安全和表现力。说白了,可选类型的引入既安全写起来有便捷。

二、Optional类型的实现

var optionalInteger: Int?

var optionalInteger: Int!

其中?和!都是可选类型的语法糖。

三、Optional类型的本质

Optional其实是个枚举(enum)(严格来讲:应该是enum和泛型为基础的高阶抽象类型),分别是None和Some(T),如果可选类型为nil就会命中None的Case。

enum Optional<T> : NilLiteralConvertible, Reflectable {  case None  case Some(T)  //...
}

如果命中Some(T)的Case,就会得到一个“包装”后的值(a wrapped value),如果想要拿到真正的value,就需要“拆包”,否则你会得到的是Optional(value)。

四、Optional类型的运用(拆包)

1、可选绑定

此种情况如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在if和while语句中来对可选类型的值进行判断并把值赋给一个常量或者变量。

基本写法:

if let constantName = someOptional {statements
}

示例:

var myString:String?
myString = "Hello, Swift!"
if let yourString = myString {print("你的字符串值为 - \(yourString)")
}else{print("你的字符串没有值")
}

2、强制解析

示例:

var myString:String?
myString = "Hello, world!"
if myString != nil {// 强制解析print( myString! )
}else{print("myString 值为 nil")
}

此时如果myString为nil,那么以上代码将会出现运行时错误。

五、Optional类型注意事项

1、使用!进行强制解包时,要确保变量值是非nil的

var str1:String?  // str1值可能是传过来的值或者从服务器获取的值
let msg = "Hi"
let txt = msg + str1!  // runtime error

所以,需要谨慎使用。

2、??运算符(空和运算符)

这是一个常见而且非常有用的操作符。我们在解包变量时,时常被提示提供一个default value。

它的作用如下:

(以下代码,摘录自https://www.jianshu.com/p/e304658fbfca?utm_source=oschina-app):

// 写法一:可选绑定(Optional Binding)
var username = ""
if let name = inputName {username = name
} else {username = "Guest"
}
// 写法二:三目运算符(ternary operator)
let username = inputName != nil ? inputName! : "Guest"

以上代码等同于:

let username = inputName ?? "Guest" 

a??b的意思是:可选类型a先进行判空判断,如果a包含一个值,就进行解封,否则就返回默认值b。注意:表达式a必须是Optional类型,默认值b的类型须要和a存储值的类型保持一致。

注意:??有时也有可能表示多重Optional,例如:

var string: String? = "string"
var anotherString: String?? = string

我们可以很明白地知道 anotherString 是 Optinal<Optional<String>>

3、Optional Chaining可选链

Swift官网有介绍如下:

Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

大致意思:

可选链是查询和调用当前可能为零的可选链上的属性、方法和下标的过程。如果可选项包含值,则属性、方法或下标调用成功;如果可选值为nil,则属性、方法或下标调用将返回nil。多个查询可以链接在一起,如果链中的任何链接为零,则整个链都会正常失败。

示例如下:

class Person {var residence: Residence?
}
class Residence {var numberOfRooms = 1
}
let john = Person()
//如果写成强制解包,此段代码会有运行时报错
let roomCount = john.residence!.numberOfRooms
//正确写法
//john.residence = Residence()
if let roomCount = john.residence?.numberOfRooms {print("John's residence has \(roomCount) room(s).")
} else {print("Unable to retrieve the number of rooms.")
}

六、参考资料

The Basics — The Swift Programming Language (Swift 5.5)

Swift中 !和 ?的区别及使用 - 简书

Swift 可选(Optionals)类型 | 菜鸟教程

swift 中的 ?? - 简书

iOS开发笔记之九十四——Swift中的可选类型Optional相关推荐

  1. Swift中的可选类型(Optional)

    为什么80%的码农都做不了架构师?>>>    Swift中的可选类型(Optional) ##什么是Optional Optional在Swift中表示可选类型,那么什么是可选类型 ...

  2. Android开发笔记(九十四)图片的基本加工

    位图管理Bitmap Android上的图形使用Drawable类,而位图管理则使用Bitmap类,java上与之对应的是awt包中的BufferedImage.Android开发中有需要对jpg.p ...

  3. iOS开发笔记 - 语言篇之Swift

     2014年的苹果全球开发者大会(WWDC),当Craig Federighi向全世界宣布"We have new programming language"(我们有了新的编程语言 ...

  4. Swift中关于可选类型(?)与强制解析(!)的特性

    2019独角兽企业重金招聘Python工程师标准>>> Swift中问号表示这是一个可选类型,白话翻译:某个常量或者变量可能是一个类型,也可能什么都没有,我不确定它是否真的会有值,也 ...

  5. iOS开发笔记之九十——在OC项目中支持Swift

    *****阅读完此文,大概需要5分钟****** 这个过程不复杂,但是有些问题遇到了可能就会捣弄很久,特此输出此文,希望可以帮助大家快速解决相应的问题. 一.配置步骤 1.主项目中添加工程名-Brid ...

  6. Android开发笔记(九十五)自定义Drawable

    Drawable Bitmap是Android对图像的定义描述,而Drawable则是对图像的展现描述,在View视图中显示图像都是通过Drawable来实现的.其中有关Bitmap的介绍参见< ...

  7. iOS开发笔记 - 网络篇

    计算机网络基础   计算机网络是多台独立自主的计算机互联而成的系统的总称,最初建立计算机网络的目的是实现信息传递和资源共享.   如果说计算机是第二次世界大战的产物,那么计算机网络则是美苏冷战的产物. ...

  8. iOS开发笔记-两种单例模式的写法

    iOS开发笔记-两种单例模式的写法 单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h"st ...

  9. Android开发笔记(九十)建造者模式

    基本概念 建造者模式是一种常用的设计模式,它用于把类的表现和构建分离开来.引入建造者模式的缘由,且看博主下面细细道来. 公开属性 一般我们定义一个类的属性,如果属性是公开的,那可以直接对该类的属性赋值 ...

最新文章

  1. python方法调用名字不一样_python中调用父类同名方法
  2. illegal instruction错误
  3. bs4之标签树的平行遍历
  4. PLSQL developer 连接64位oracle 11.2G
  5. camel 数据库_使用Camel在来自不同来源的Solr中索引数据
  6. 让AMD在中国发声 APU14技术创新大会首次在华召开
  7. 抽象思想解读Linux进程描述符
  8. java 百度api接口开发_百度熊掌号使用Java工具类对接API推送接口进行文章推送实例详解...
  9. 对anagrams分组 Group Anagrams
  10. 13.程序员的自我修养---运行库实现
  11. 普中科技51单片机——keil的介绍和PZ-ISP无法烧录问题
  12. OpenMP4.0: #pragma openmp simd实现SIMD指令优化(ARM,X86,MIPS)
  13. 左右手桌面股票盯盘软件(DesktopStockTracking)
  14. 利用MATLAB实现Sobel边缘检测
  15. rh系列服务器上电后按,SV12 RH系列机架服务器操作系统安装.pdf
  16. java-web阶段性总结
  17. 迷宫小游戏c语言代码,C语言编写的迷宫小游戏-源代码
  18. win10 任务管理器、注册表编辑被禁用如何解决? -伽卡他卡禁用任务管理器
  19. 微信小程序——简单计算器
  20. 视觉SLAM笔记(33) 对极约束求解相机运动

热门文章

  1. 网络文化与伦理【0948】
  2. Python内置函数—vars的具体使用方法
  3. 阿里云NLP接口调用
  4. Android学习之仿QQ侧滑功能的实现
  5. 优课联盟 实境英语 Test for Unit 5
  6. 临界区(临界段)的含义
  7. 用Python制作一个简单的球球大作战
  8. 25.Flink监控\什么是Metrics\Metrics分类\Flink性能优化的方法\合理调整并行度\合理调整并行度\Flink内存管理\Spark VS Flink\时间机制\容错机制等
  9. 马云:我们唯一拥有的就是相信梦想,Never give up!
  10. 网页代码基本结构以及html标签的使用