博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift :?和 !
阅读量:5074 次
发布时间:2019-06-12

本文共 2304 字,大约阅读时间需要 7 分钟。

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

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

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

 

[plain] 
 
  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类型,后面跟一个?就是了。

 

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

 

 

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

 

[plain] 
 
  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)时,对于可选代理方法,也需要在调用时在函数名后跟着?,如:

 

 

[plain] 
 
  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.     
  9.   // other funcs ...  
  10. }  
  11.   
  12. var delegate: HttpRequestDelegate?  
  13. var downloadData = NSMutableData()  
  14. delegate.requestFinished(self, downloadData)  

 

 

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

 

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

 

隐式强拆包类型:

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

在调用时就会崩溃。

 

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

总结:

 

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

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

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

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

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

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

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

转载于:https://www.cnblogs.com/xilanglang/p/5073152.html

你可能感兴趣的文章
HDOJ 1250 Hat's Fibonacci 简单解题报告
查看>>
mvc5 + ef6 + autofac搭建项目(repository+uow)(二)
查看>>
uploadify在chrome下初始化失败,在Firefox下却可以原因探析
查看>>
HDU 2879 数论
查看>>
LA和TA
查看>>
spark性能调优之一:分配更多资源
查看>>
三种数据库访问——Spring3.2 + Hibernate4.2
查看>>
POJ 算法基础 编程题#1:集合加法
查看>>
Mahout canopy聚类
查看>>
pig入门教程(2)
查看>>
[欧拉回路] Jzoj P1319 邮递员
查看>>
XSS跨站测试代码大全
查看>>
请不要拿ipad和手机、上网本相提并论
查看>>
js把字符串(yyyymmdd)格式转换成日期格式(yyyy-mm-dd)
查看>>
如何知道linux的系统是CentOS,还是Ubuntu?
查看>>
Spring WebSocket Support官方文档+翻译
查看>>
STM32之USB电路(摘要笔记)
查看>>
php不会的点
查看>>
毫无PS痕迹 你的第一本Photoshop书pdf
查看>>
Http协议简单学习笔记
查看>>