zoukankan      html  css  js  c++  java
  • Swift :?和 !

    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.   
    5. // 判断optional是否有值  
    6. if strValue {  
    7.  // do what you need to do here  
    8. }  

    文档中有提到说,在使用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.     
    9.   // other funcs ...  
    10. }  
    11.   
    12. var delegate: HttpRequestDelegate?  
    13. var downloadData = NSMutableData()  
    14. delegate.requestFinished(self, downloadData)  

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

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


    隐式强拆包类型:

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

    在调用时就会崩溃。

    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

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

  • 相关阅读:
    “XXXXX” is damaged and can’t be opened. You should move it to the Trash 解决方案
    深入浅出 eBPF 安全项目 Tracee
    Unity3d开发的知名大型游戏案例
    Unity 3D 拥有强大的编辑界面
    Unity 3D物理引擎详解
    Unity 3D图形用户界面及常用控件
    Unity 3D的视图与相应的基础操作方法
    Unity Technologies 公司开发的三维游戏制作引擎——Unity 3D
    重学计算机
    windows cmd用户操作,添加,设备管理员组,允许修改密码
  • 原文地址:https://www.cnblogs.com/xilanglang/p/5073152.html
Copyright © 2011-2022 走看看