http://blog.csdn.net/woaifen3344/article/details/30244201

Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,

也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化

。如果在使用变量之前不进行初始化就会报错:

  1. var stringValue : String
  2. //error: variable 'stringValue' used before being initialized
  3. //let hashValue = stringValue.hashValue
  4. //                            ^
  5. let hashValue = stringValue.hashValue

出错的原因就是在使用stringValue这个变量之前,没有初始化这个变量,也就是这个变量根本就没有得到内存,

这时就会出错。

那么我们可以使用optional类型,后面跟一个?就是了。

  1. // 这就是optional, strValue自动得到默认值:nil
  2. // 这个nil跟Objective-C中的nil不同,不是指针,而是表示值不存在。
  3. var strValue: String?
  4. // 判断optional是否有值
  5. if strValue {
  6. // do what you need to do here
  7. }

文档中有提到说,在使用Optional值的时候需要在具体的操作,比如调用方法、属性、下标索引等前面需要加上一个?,如果是nil值(不存在值),也就是Optional.None,会跳过后面的操作不执行,如果有值,就是Optional.Some可能就会拆包(unwrap),然后对拆包后的值执行后面的操作,来保证执行这个操作的安全性,比如Optional binding:

  1. // optional binding
  2. // 如果strValue == nil, 那么结果就是nil,不会调用String的hasValue
  3. // 如果strValue != nil, 就返回strValue对应的hashValue值并赋值给常量hashValue
  4. if let hashValue = strValue?.hashValue {
  5. // do something if neccessary
  6. }

在写协议(protocol)时,对于可选代理方法,也需要在调用时在函数名后跟着?,如:

  1. // @objc 是用于处理Swift与OC之间的转换的,由于@optional是OC中的关键字,
  2. // 所以在protocol之前需要添加上@objc。
  3. @objc protocol HttpRequestDelegate {
  4. // @optional 说明这个代理方法是可选方法,
  5. // 那么在调用的时候,需要这样调用:delegate?.requestFinished?(self, downloadData)
  6. // 其中delegate?是因为delegate也是optional的
  7. @optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)
  8. // other funcs ...
  9. }
  10. var delegate: HttpRequestDelegate?
  11. var downloadData = NSMutableData()
  12. delegate.requestFinished(self, downloadData)

当然我们也可以使用!来强制拆包,这是我们在保证有值的情况下才会这么用:

  1. var strValue: String?
  2. strValue = "1234"
  3. let integer = strValue!.toInt()
  4. // 更安全的写法是
  5. if strValue {
  6. let integer = strValue!.toInt()

隐式强拆包类型:

使用!来声明变量,会成为隐式强拆包可选类型,这表示这个类型永远不会出现nil的情况,但一旦出来,

在调用时就会崩溃。

  1. // Implicitly Unwrapped Optionals
  2. // 使用这种方式声明的话,在调用时不需要使用?或!来说明。
  3. var myLabel: UILabel!
  4. myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))
  5. myLabel.text = "label"

总结:

通常在什么情况下才会使用optional类型呢?

(1)当我们需要声明这样一个变量,变量在设计初始化函数中没有进行初始化时,就需要声明这个变量为optional类型。因为变量在使用前必须先

声明,并且在设计初始化函数中进行初始化。比如我们在viewDidLoad函数中才进行初始化的控件(类成员),就需要声明为optional且必须是var声明,

因为let声明的常量只能是在初始化函数中进行初始化。

(2)当我们不知道是否会有值的时候,这个变量可以声明为optional,比如代理,我们并没有要求必须传代理过来,那么就需要声明为optional。

(3)作为函数参数时,如果这个参数可以没有值,那么就使用optional类型,比如传代理的时候,通常就是可选的,可以设置为nil

......暂时只想到这些,任何人都可以继续往下补充!

版权声明:本文为博主原创文章,未经博主允许不得转载。

Swift 学习之二十一:?和 !(详解)的更多相关文章

  1. CDN学习笔记二(技术详解)

    一本好的入门书是带你进入陌生领域的明灯,<CDN技术详解>绝对是带你进入CDN行业的那盏最亮的明灯.因此,虽然只是纯粹的重点抄录,我也要把<CDN技术详解>的精华放上网.公诸同 ...

  2. Python3网络学习案例二:traceroute详解

    1. 写在前面 本文是基于上一篇"ping详解"写的: 不同操作系统下的命令也不同,本文仅针对windows系统,命令为"tracert xxx",效果如下 2 ...

  3. C#学习笔记二: C#类型详解

    前言 这次分享的主要内容有五个, 分别是值类型和引用类型, 装箱与拆箱,常量与变量,运算符重载,static字段和static构造函数. 后期的分享会针对于C#2.0 3.0 4.0 等新特性进行. ...

  4. 【Java学习笔记之三十一】详解Java8 lambda表达式

    Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前 ...

  5. Spark2.0学习(二)--------RDD详解

    添加针对scala文件的编译插件 ------------------------------ <?xml version="1.0" encoding="UTF- ...

  6. Linux学习之文件特殊权限详解(SetUID、SetGID、Sticky BIT)(十一)

    Linux学习之文件特殊权限详解(SetUID.SetGID.Sticky BIT) 目录 SetUID SetGID Sticky BIT SetUID SetUID简介 只有可以执行的二进制程序和 ...

  7. Python学习一:序列基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...

  8. IP2——IP地址和子网划分学习笔记之《子网掩码详解》

    2018-05-04 16:21:21   在学习掌握了前面的<进制计数><IP地址详解>这两部分知识后,要学习子网划分,首先就要必须知道子网掩码,只有掌握了子网掩码这部分内容 ...

  9. Spring MVC 学习)——控制器与@RequestMapping详解

    Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解 一.控制器定义 控制器提供访问应用程序的行为,通常通过服务接口定义或注解定义两种方法实现. 控制器解析用户的请求 ...

随机推荐

  1. Git创建project

    1.登录创建新仓库 命名 2.https://gitforwindows.org/  下载git的windows客户端,输入git查看是否成功 3.创建文件夹,写内容并查看,和linux指令一样 4. ...

  2. 51单片机数码管字符H自右向左移动

    #include <reg51.h> #define uint unsigned int #define uchar unsigned char sfr P0M0 = 0x94; sfr ...

  3. Web负载均衡技术

    Web负载均衡(Load Balancing),简单地说就是给我们的服务器集群分配“工作任务”,而采用恰当的分配方式,对于保护处于后端的Web服务器来说,非常重要. 负载均衡的策略有很多,我们从简单的 ...

  4. ThinkPHP5 Model分层及多对多关联的建立

    笔者最近入手ThinkPHP5,准备用它来实现一个学生作业管理系统.简单的说就是学生在上面交老师布置的课程作业,老师也可以发布修改作业.过程中势必会碰到学生.班级和老师之间的关系.它们之间的关系是多对 ...

  5. POJ 1703 Find them, Catch them(并查集拓展)

    Description The police office in Tadu City decides to say ends to the chaos, as launch actions to ro ...

  6. mysql 数据库新增用户

    1.user表中host为%含义: Host列指定了允许用户登录所使用的IP,比如user=root Host=192.168.1.1.这里的意思就是说root用户只能通过192.168.1.1的客户 ...

  7. poj1789 Truck History最小生成树

    Truck History Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 20768   Accepted: 8045 De ...

  8. 基于SDN的IP RAN网络虚拟化技术

    http://www.zte.com.cn/cndata/magazine/zte_technologies/2014/2014_4/magazine/201404/t20140421_422858. ...

  9. golang and intellij

    有一个项目,混合了java和go,需要在intellij中安装go的插件. OK,网上的信息简直混乱不堪,两个流派,一个流派就是装插件,一个流派就是编译插件,各种折腾,还是安装不了,谁知柳暗花明又一村 ...

  10. [LeetCode] 70. Climbing Stairs(斐波那契数列)

    [思路] a.因为两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1); b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2) c.由a.b ...