Swift当中的Optional类型,表明一个变量可能有确认的值,也可能不包含任何值。不包含任何值在Swift当中,就是一个nil。

Swift当中的变量或者常量,在使用之前必须得赋值,但是对于Optional类型来说,情形有点不一样。对于Optional变量来说,使用之前可以不用赋值:

var a: Int?
var b = a //正确
let c = a //正确

这是因为对于Optional变量来说,如果不赋任何值,编译器默认赋nil。

但是上述情况对于Optional常量不适用,如果Optional常量未显示赋值就是用,编译器报错:

let c: Int?
var a = c //报错

即使显示对Optional常量赋值nil,也是可以的:

let c: Int?
c = nil
var a = c //正确

Swift当中不能重复声明变量,即使变量名字相同,类型不同也不行,或者将同一个名字声明为变量的同时,还声明成常量也不行。在这里,将相同名字的变量声明成Optional类型也不行:

var a:Int
var a:Int? //报错 let a:Int
var a:Int? //报错 let a:Int
let a:Int? //报错

总结起来就是一句话,如果变量或者常量相同,那么就只能声明一次。

Swift中Optional的变量或者常量,不能直接复制给非Optional的变量或者常量,但是反过将非Optional的变量或者常量,赋值给Optional的变量或者常量是没问题的:

let a: Int? = 1
let b: Int = a //报错 var a: Int? = 1
var b: Int = a //报错 let a: Int = 1
let b: Int? = a //可以 var a: Int = 1
var b: Int? = a //可以

Forced Unwrapping

在使用Optional变量或者常量之前,一定要使用if语句测试,看他们是否是nil,如果确认不是nil,那就可以进行Forced Unwrapping,也就是在Optional变量或者常量豁免适用!,以此向编译器说明,你确定了该变量或者常量有值,可以放心使用:

var a: Int? = 1

if a != nil {
print(a!) //这里如果不加!,输出Optional(1),并且编译器会有警告
}

为什么对于Optional类型使用前要先监测呢?

因为如果不检测就是用!求值,如果求出来的值是nil,会发生运行时错误:

var a: Int?
print(a!) //发生运行时错误

Optional Binding

文字解释Optional Binding费劲,直接看代码:

var a: Int? = 1

if let b = a {  //if语句当中的let b = a这块就是Optional Biding
print(b)
} else {
print("nil")
}

上面if语句当中的let b = a就是Optional Binding,如果a有值,那么a的值会赋给b,否则,if语句不成立,将执行else语句。

这里进行Optional Binding的时候,适用var b = a也是没有问题的,但是由于编译器发现你对b没有改动,会出警告,提示你最好使用let。

另外一个需要注意的地方就是,这里声明的b,只能在if语句内部使用。

多个Optional Bindings可以一起使用,当中用逗号隔开就行,如果任何一个Optional Binding为nil,那么if语句就不会执行:

var a: Int? = 1
var b: Int? = nil
if let c = a, let d = b { //if语句当中的let b = a这块就是Optional Biding 整个if语句输出nil
print("non nil")
} else {
print("nil")
}

对于Optional Binding来说,出了在if语句当中使用,还可以在while语句当中使用。

Implicitly Unwrapped Optionals

前面提到过对于Optional类型的变量或者常量来说,无法直接赋值给非Optional的变量或者常量。但是有些时候,对于程序里面的Optional类型,我们使用之前是可以肯定这个类型的变量或者常量是有值的,这时候如果进行Force Unwrapping就比较麻烦,这个时候就可以利用Implicitly Unwrapped Optionals了。一个变量或者常量声明成Implicitly Unwrapped Optionals和声明成Optional非常相似,只需要把?换成!:

var a: Int? //Optional
var b: Int! //Implicitly Unwrapped Optionals

编译器对于Implicitly Unwrapped Optionals的使用是这样的,首先把这个变量或者常量当成普通的Optional来对待,如果不行,那么编译器就自动进行Force-Unwrapping的操作:

var a: Int! = 2
var b = a //b类型是Optional的
var c: Int = a //无需对a显示进行Fource-Wrapping加! c变量是非 optional 的,因为类型声明时是确定的

对于mplicitly Unwrapped Optionals需要注意,使用的时候千万不能是nil的,否则会报运行时错误。

Swift中的Optional类型的更多相关文章

  1. Swift中的Optional类型 (可选类型)与强制解包 ? !

    我们在swift的开发中会经常遇见?和! ,理解这两个符号深层次的内容对我们的开发是相当有利的: 目前网上对swift3.0的教程还相当的少,如果去搜索会发现早期的说法,在定义变量的时候,swift是 ...

  2. [翻译]理解Swift中的Optional

    原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...

  3. Swift中的Void类型与空元祖表达式

    可能有不少Swift开发者会忽略这么一个细节:在Swift中,Void类型其实是一个别名类型,而其真正的类型为(),即一个空元祖(empty tuple)! 这种语言特性给Swift带来了一些比较方便 ...

  4. swift中,Optional、?与!之间的关系

    swift中,Optional.?与!之间的关系 Optional <ClassName> 与 ClassName? 等价 对 ClassName! 强制取值会导致崩溃(如果对象为nil时 ...

  5. Swift中的指针类型

    Swift编程语言为了能与Objective-C与C语言兼容,而引入了指针类型.尽管官方不建议频繁使用指针类型,但很多时候,使用指针能完成更多.更灵活的任务.比如,我们要实现一个交换两个整数值的函数的 ...

  6. swift中的可选类型

    可选类型也是Swift语言新添加的对象.主要是为了解决对象变量或常量为空的情况.在前面定义的变量和常量都不能为空.里面必须要有值. Swift中的可选类型则允许变量(常量)中没有值(被设为nil).要 ...

  7. Swift中关于任意类型的数组

    在Objc中你是不可以把一个非对象类型放入数组的,你必须将其"封箱",然后再放入数组. 在Swift中你可将非对象类型轻松放入数组: let ary = [1,2,3] 你可以明确 ...

  8. Swift——(六)Swift中的值类型

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/twlkyao/article/details/34855597     在Swift中,结构体和枚举 ...

  9. Swift中的集合类型

    一.引子: 在2014年10月TIOBE编程语言排行榜中,Swift位居第18位,从2014WWDC发布会首次公布至今不到半年时间,swift一直受到编程人 员的追捧,其热衷程度并不亚于当红巨星Tay ...

  10. Swift中的Result 类型的简单介绍

    Swift 5引入了一个新的Result类型, 它使用枚举来处理异步函数的结果. 苹果文档对该类型的描述: A value that represents either a success or a ...

随机推荐

  1. 数据库锁起来了,把事务清掉sql

    select concat('kill ',id,';') from information_schema.`PROCESSLIST` where state !='executing' 将上述代码执 ...

  2. #轻重链剖分,线段树#洛谷 3703 [SDOI2017]树点涂色

    题目传送门 分析 可以发现相同的颜色一定组成一个连通块. 那么操作2就相当于 \(f_x+f_y-2*f_{lca}+1\) 操作3就相当于询问 \(f\) 的最大值. 最关键的就是操作1,考虑往上跳 ...

  3. #树形dp,二次扫描换根法#JZOJ 3501 消息传递 with others

    目录 JZOJ 3501 消息传递 题目 分析 代码 简单写就能跳过之题目 JZOJ 3500 物语 题目 分析 代码 JZOJ 3757 洛谷 2354 [NOI 2014] 随机数产生器 题目 分 ...

  4. #树状数组,线段树,离散#JZOJ 3854 分组

    题目 Bsny所在的精灵社区有\(n\)个居民,每个居民有一定的地位和年龄,\(r_i\)表示第\(i\)个人的地位,\(a_i\)表示第\(i\)个人的年龄. 最近社区里要举行活动,要求几个人分成一 ...

  5. 上海站报名启动! 2023年开源产业生态大会OpenHarmony生态分论坛

      作为年内开源领域不容错过的科技盛宴,2023年开源产业生态大会将于12月19日在上海盛大开幕.本次活动由上海市经济和信息化委员会.上海市科学技术协会和"科创中国"开源创新联合体 ...

  6. Jchardet——支持检测并输出文件编码方式的组件

      简介 Jchardet是OpenAtom OpenHarmony(以下简称"OpenHarmony")系统的一款检测文本编码的组件.当上传一个文件时,组件可以检测并输出该文件中 ...

  7. C 语言注释和变量详解

    C 语言中的注释 C语言中可以使用注释来解释代码并使其更具可读性.它还可以在测试替代代码时防止执行. 单行注释 单行注释以两个斜杠 (//) 开头. // 和行末之间的任何文本都会被编译器忽略(不会被 ...

  8. Python格式化字符串:%、format、f-string

    目前Python格式化字符串的方式有三种: 1. % 2.format 3.f-string % 格式化常用方法: # % 格式化字符串 s1 = 'name is %s' % ('zhangsan' ...

  9. Qt操作ini文件

    操作文件,无非就是读与写,以下为Qt读写ini文件的代码. demo: #include "widget.h" #include <QApplication> #inc ...

  10. 【Nano Framework ESP32 篇】刷入 nanoCLR 固件以及相关问题

    老周在几个世纪前曾写过树莓派相关的 iOT 水文,之所以没写 Nano Framework 相关的内容,是因为那时候这货还不成熟,可玩性不高.不过,这货现在已经相对完善,老周都把它用在项目上了--第一 ...