Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化。如果在使用变量之前不进行初始化就会报错:

var stringValue : String
//error: variable 'stringValue' used before being initialized
//let hashValue = stringValue.hashValue
//                            ^
let hashValue = stringValue.hashValue

上面了解到的是普通值,接下来Optional值要上场了。经喵神提醒,Optional其实是个enum,里面有NoneSome两种类型。其实所谓的nil就是Optional.None, 非nil就是Optional.Some, 然后会通过Some(T)包装(wrap)原始值,这也是为什么在使用Optional的时候要拆包(从enum里取出来原始值)的原因, 也是PlayGround会把Optional值显示为类似{Some "hello world"}的原因,这里是enum Optional的定义:

enum Optional<T> : LogicValue, Reflectable {case Nonecase Some(T)init()init(_ some: T)/// Allow use in a Boolean context.func getLogicValue() -> Bool/// Haskell's fmap, which was mis-namedfunc map<U>(f: (T) -> U) -> U?func getMirror() -> Mirror
}

声明为Optional只需要在类型后面紧跟一个?即可。如:

var strValue: String?   //?相当于下面这种写法的语法糖
var strValue: Optional<Int>

一旦声明为Optional的,如果不显式的赋值就会有个默认值nil。判断一个Optional的值是否有值,可以用if来判断:

if strValue {//do sth with strValue
}

然后怎么使用Optional值呢?文档中也有提到说,在使用Optional值的时候需要在具体的操作,比如调用方法、属性、下标索引等前面需要加上一个?,经喵神指正,”Optional Chaining的问号的意思是询问是否响应后面这个方法,和原来的isResponseToSelector有些类似”,如果是nil值,也就是Optional.None,固然不能响应后面的方法,所以就会跳过,如果有值,就是Optional.Some,可能就会拆包(unwrap),然后对拆包后的值执行后面的操作,比如:

let hashValue = strValue?.hashValue

strValue是Optional的字符串,如果strValue是nil,则hashValue也为nil,如果strValue不为nil,hashValue就是strValue字符串的哈希值

到这里我们看到了?的两种使用场景:
1.声明Optional值变量
2.用在对Optional值操作中,用来判断是否能响应后面的操作

另外,对于Optional值,不能直接进行操作,否则会报错:

//error: 'String?' does not have a member named 'hashValue'
//let hashValue = strValue.hashValue
//                ^        ~~~~~~~~~let hashValue = strValue.hashValue

上面提到Optional值需要拆包(unwrap)后才能得到原来值,然后才能对其操作,那怎么来拆包呢?拆包提到了几种方法,一种是Optional Binding, 比如:

if let str = strValue {let hashValue = str.hashValue
}

还有一种是在具体的操作前添加!符号,好吧,这又是什么诡异的语法?!

直接上例子,strValue是Optional的String:

let hashValue = strValue!.hashValue

这里的!表示“我确定这里的的strValue一定是非nil的,尽情调用吧” ,比如这种情况:

if strValue {let hashValue = strValue!.hashValue
}

{}里的strValue一定是非nil的,所以就能直接加上!,强制拆包(unwrap)并执行后面的操作。 当然如果不加判断,strValue不小心为nil的话,就会出错,crash掉。

考虑下这一种情况,我们有一个自定义的MyViewController类,类中有一个属性是myLabel,myLabel是在viewDidLoad中进行初始化。因为是在viewDidLoad中初始化,所以不能直接声明为普通值:var myLabel : UILabel,因为非Optional的变量必须在声明时或者构造器中进行初始化,但我们是想在viewDidLoad中初始化,所以就只能声明为Optional:var myLabel: UILabel?, 虽然我们确定在viewDidLoad中会初始化,并且在ViewController的生命周期内不会置为nil,但是在对myLabel操作时,每次依然要加上!来强制拆包(在读取值的时候,也可以用?,谢谢iPresent在回复中提醒),比如:

myLabel!.text = "text"
myLabel!.frame = CGRectMake(0, 0, 10, 10)
...

对于这种类型的值,我们可以直接这么声明:var myLabel: UILabel!, 果然是高(hao)大(gui)上(yi)的语法!, 这种是特殊的Optional,称为Implicitly Unwrapped Optionals, 直译就是隐式拆包的Optional,就等于说你每次对这种类型的值操作时,都会自动在操作前补上一个!进行拆包,然后在执行后面的操作,当然如果该值是nil,也一样会报错crash掉。

var myLabel: UILabel!  //!相当于下面这种写法的语法糖
var myLabel: ImplicitlyUnwrappedOptional<UILabel>

那么!大概也有两种使用场景
1.强制对Optional值进行拆包(unwrap)
2.声明Implicitly Unwrapped Optionals值,一般用于类中的属性

转载于:https://www.cnblogs.com/zhepama/p/3774887.html

Swift中的问号?和感叹号!相关推荐

  1. Angular中的 问号 和 感叹号 作用

    ?用来检查问好前面的变量是否null或者undefined时,程序不会出错. stu3: Student;<h1>stu3 id{{stu3?.id}}</h1> // stu ...

  2. swift 中的 感叹号 问号 和 双问号用法详解

    首先介绍一下swift 中的 Optional!  点到 Optional 的头文件可以看到, Optional 其实是个enum,里面有 case None 和 case Some(Wrapped) ...

  3. Swift 总结使用问号(?)和感叹号(!)-备用

    在使用可选类型和可选链时,多次使用了问号(?)和感叹号(!),但是它们的含义是不同的,下面我来详细说明一下. 1. 可选类型中的问号(?) 声明这个类型是可选类型,访问这种类型的变量或常量时要使用感叹 ...

  4. 设备管理器其它设备Android叹号,设备管理器中的设备显示感叹号/问号/叉号的解决方法...

    设备管理器是Windows操作系统自带的管理工具,其为用户提供了设置设备.启用/禁用设备.更新设备驱动程序等多种强大的功能,帮助用户能后更好的使用电脑的硬件设备,而部分用户在打开设备管理器时,发现部分 ...

  5. java中使用句号问号和感叹号分割_逗号,句号,感叹号和问号

    2011年12月6日 星期二 天气:阴雨 逗号,句号,感叹号和问号 进入到12月份,成都的冬天也随之而来,学习任务不断加重,天气也日渐寒冷,这是对一年级孩子身心的考验.在这里再简要说一下这学期语文的教 ...

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

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

  7. Swift中 !和 ?的区别及使用与Swift的Guard语句

    1.swift中的!和?到底是什么? ?和!其实分别是swift语言中的一种可选类型(Optional)操作的语法糖. 1.1可选类型是个什么东西? swift中可以声明一个没有初始值的属性,swif ...

  8. Swift中方法的多面性

    虽然 Objective-C 的语法相对于其他编程语言来说写法有点奇怪,但是当你真正使用的时候它的语法还是相当的简单.下面有一些例子: + (void)mySimpleMethod {// 类方法// ...

  9. Swift中的UIKit重力学(一)

    重力学这个名词不论在哪个行业领域听起来似乎都很高大上.那么在Swift中的重力学是什么呢?那就是将我们移动端屏幕上毫无生命力的东西也置于万有引力中,使它们能够展现出好像真的由于引力而向下坠落以及碰到物 ...

最新文章

  1. xcode 8 重新支持插件
  2. 软件驱动安装在docker_docker 安装软件
  3. 7z压缩文档的powershell示例
  4. 基于JAVA+SpringBoot+Mybatis+MYSQL的图书管理系统
  5. JAVA作业-简易计算器
  6. .NetCore + NSwag生成可交互API文档
  7. Msfconsole的基本使用
  8. 【学习笔记】极其美妙的算法——FFT(快速傅里叶变换)
  9. 产品经理笔试题分析(一)
  10. 基于python的酒店管理系统_基于Web酒店管理系统的设计与实现
  11. Apache部署超详细教程
  12. 西安电子科技大学计算机类考研数据速览
  13. BLE-1の蓝牙4.0协议栈概览
  14. linux中apache与tomcat如何使用
  15. 关于MediaCode播放H265/hevc的总结
  16. 【爬虫入门】获取响应内容(即读取网页html的源码)
  17. kankan转载:Android实现3d翻转效果
  18. Git三大特色之Branch(分支)
  19. java服务器访问白名单
  20. (已解决)RedisTemplate写入数据 \xAC\xED\x00\x05t\x00 序列化问题

热门文章

  1. 计算机如何表示色彩?
  2. 2022-2028年中国数字化档案加工行业市场深度分析及发展策略分析报告
  3. 2022-2028年中国香薰行业市场研究及前瞻分析报告
  4. GCC 连接器、链接标准库 gcc -l、链接手动创建库(指定目录的库 gcc -L)
  5. 剑指offer 40.最小的 K 个数 python代码
  6. 如何在小型pcb的移动设备上获得更好的无线性能
  7. 在react hook里使用mobx(配置mobx依赖)
  8. pip install scipy和matplotlib报错的问题详解:(pip install其它时报错通用)
  9. RxJava debounce()和throttleWithTimeout()
  10. CountDownTimer 实现验证码倒计时