Swift語言使用var定義變量,但和別的語言不同,Swift里不會自動給變量賦初始值,
也就是說變量不會有默認值,所以要求使用變量之前必須要對其初始化
。如果在使用變量之前不進行初始化就會報錯:
- var stringValue : String
- //error: variable 'stringValue' used before being initialized
- //let hashValue = stringValue.hashValue
- // ^
- let hashValue = stringValue.hashValue
出錯的原因就是在使用stringValue這個變量之前,沒有初始化這個變量,也就是這個變量根本就沒有得到內存,
這時就會出錯。
那么我們可以使用optional類型,后面跟一個?就是了。
- // 這就是optional, strValue自動得到默認值:nil
- // 這個nil跟Objective-C中的nil不同,不是指針,而是表示值不存在。
- var strValue: String?
-
- // 判斷optional是否有值
- if strValue {
- // do what you need to do here
- }
文檔中有提到說,在使用Optional值的時候需要在具體的操作,比如調用方法、屬性、下標索引等前面需要加上一個
?,如果是nil值(不存在值),也就是Optional.None,會跳過后面的操作不執行,如果有值,就是Optional.Some可能就會拆包(unwrap),然后對拆包后的值執行后面的操作,來保證執行這個操作的安全性,比如Optional binding:
- // optional binding
- // 如果strValue == nil, 那么結果就是nil,不會調用String的hasValue
- // 如果strValue != nil, 就返回strValue對應的hashValue值并賦值給常量hashValue
- if let hashValue = strValue?.hashValue {
- // do something if neccessary
- }
在寫協議(protocol)時,對于可選代理方法,也需要在調用時在函數名后跟著?,如:
- // @objc 是用于處理Swift與OC之間的轉換的,由于@optional是OC中的關鍵字,
- // 所以在protocol之前需要添加上@objc。
- @objc protocol HttpRequestDelegate {
- // @optional 說明這個代理方法是可選方法,
- // 那么在調用的時候,需要這樣調用:delegate?.requestFinished?(self, downloadData)
- // 其中delegate?是因為delegate也是optional的
- @optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)
-
- // other funcs ...
- }
-
- var delegate: HttpRequestDelegate?
- var downloadData = NSMutableData()
- delegate.requestFinished(self, downloadData)
當然我們也可以使用!來強制拆包,這是我們在保證有值的情況下才會這么用:
- var strValue: String?
- strValue = "1234"
-
- let integer = strValue!.toInt()
- // 更安全的寫法是
- if strValue {
- let integer = strValue!.toInt()
- }
隱式強拆包類型:
使用!來聲明變量,會成為隱式強拆包可選類型,這表示這個類型永遠不會出現nil的情況,但一旦出來,
在調用時就會崩潰。
- // Implicitly Unwrapped Optionals
- // 使用這種方式聲明的話,在調用時不需要使用?或!來說明。
- var myLabel: UILabel!
-
- myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))
- myLabel.text = "label"
總結:
通常在什么情況下才會使用optional類型呢?
(1)當我們需要聲明這樣一個變量,變量在設計初始化函數中沒有進行初始化時,就需要聲明這個變量為optional類型。因為變量在使用前必須先
聲明,并且在設計初始化函數中進行初始化。比如我們在viewDidLoad函數中才進行初始化的控件(類成員),就需要聲明為optional且必須是var聲明,
因為let聲明的常量只能是在初始化函數中進行初始化。
(2)當我們不知道是否會有值的時候,這個變量可以聲明為optional,比如代理,我們并沒有要求必須傳代理過來,那么就需要聲明為optional。
(3)作為函數參數時,如果這個參數可以沒有值,那么就使用optional類型,比如傳代理的時候,通常就是可選的,可以設置為nil
......暫時只想到這些,任何人都可以繼續往下補充!
本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請
點擊舉報。