1. 程式人生 > >swift學習第七天 ?和!

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 
上面瞭解到的是普通值,接下來Optional值要上場了。Optional其實是個enum,裡面有None和Some兩種型別。其實所謂的nil就是Optional.None, 非nil就是Optional.Some, 然後會通過Some(T)包裝(wrap)原始值,這也是為什麼在使用Optional的時候要拆包(從enum裡取出來原始值)的原因, 也是PlayGround會把Optional值顯示為類似{Some "hello world"}的原因,這裡是enum Optional的定義:
  1. enum
     Optional<T> : LogicValue, Reflectable { 
  2.     case None 
  3.     case Some(T) 
  4.     init() 
  5.     init(_ some: T) 
  6.     /// Allow use in a Boolean context.
  7.     func getLogicValue() -> Bool 
  8.     /// Haskell's fmap, which was mis-named
  9.     func map<U>(f: (T) -> U) -> U? 
  10.     func getMirror() -> Mirror 
宣告為Optional只需要在型別後面緊跟一個?即可。如:
  1. var strValue : String?  
一旦宣告為Optional的,如果不顯式的賦值就會有個預設值nil。判斷一個Optional的值是否有值,可以用if來判斷:
  1. if strValue { 
  2.     //do sth with strValue
然後怎麼使用Optional值呢?文件中也有提到說,在使用Optional值的時候需要在具體的操作,比如呼叫方法、屬性、下標索引等前面需要加上一個?,“Optional Chaining的問號的意思是詢問是否響應後面這個方法,和原來的isResponseToSelector有些類似”,如果是nil值,也就是Optional.None,固然不能響應後面的方法,所以就會跳過,如果有值,就是Optional.Some,可能就會拆包(unwrap),然後對拆包後的值執行後面的操作,比如:
  1. let hashValue = strValue?.hashValue  
strValue是Optional的字串,如果strValue是nil,則hashValue也為nil,如果strValue不為nil,hashValue就是strValue字串的雜湊值 到這裡我們看到了?的兩種使用場景: 1.宣告Optional值變數 2.用在對Optional值操作中,用來判斷是否能響應後面的操作 另外,對於Optional值,不能直接進行操作,否則會報錯:
  1. //error: 'String?' does not have a member named 'hashValue'
  2. //let hashValue = strValue.hashValue
  3. //                ^        ~~~~~~~~~
  4. let hashValue = strValue.hashValue 
上面提到Optional值需要拆包(unwrap)後才能得到原來值,然後才能對其操作,那怎麼來拆包呢?拆包提到了幾種方法,一種是Optional Binding, 比如:
  1. if let str = strValue { 
  2.     let hashValue = str.hashValue 
還有一種是在具體的操作前新增!符號,好吧,這又是什麼詭異的語法?! 直接上例子,strValue是Optional的String:
  1. let hashValue = strValue!.hashValue 
這裡的!表示“我確定這裡的的strValue一定是非nil的,盡情呼叫吧” ,比如這種情況:
  1. if strValue { 
  2.     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操作時,每次依然要加上!來強制拆包(?也OK),比如:
  1. myLabel!.text = "text"
  2. myLabel!.frame = CGRectMake(0, 0, 10, 10) 
  3. ... 
對於這種型別的值,我們可以直接這麼宣告:var myLabel: UILabel!, 果然是高(hao)大(fu)上(za)的語法!, 這種是特殊的Optional,稱為Implicitly Unwrapped Optionals, 直譯就是隱式拆包的Optional,就等於說你每次對這種型別的值操作時,都會自動在操作前補上一個!進行拆包,然後在執行後面的操作,當然如果該值是nil,也一樣會報錯crash掉。 那麼!大概也有兩種使用場景 1.強制對Optional值進行拆包(unwrap) 2.宣告Implicitly Unwrapped Optionals值,一般用於類中的屬性 Swift是門新生的語言,我們有幸見證了它的誕生,激動之餘也在佩服蘋果大刀闊斧的推出一個新的語言替代一個已經比較成熟語言的魄力,今天在知乎日報上看到一個回答是說Swift是一門玩具語言,正當想去吐槽,發現回答已經被刪除了。個人認為蘋果是很認真的推出Swift的,從Swift的各種細微的設計也能看的出來。 另外這兩個小符號就花費了我不少的時間來理解,可能依然會有錯誤和不妥之處,歡迎大家指正,本文旨在拋磚引玉。除此之外,Swift還有很多很棒的特性,WWDC 2014 會有四五個和Swift語言相關的Video,大家也可以去關注一下。 最後要感謝喵神的糾正了多處有問題的地方,thx, have fun! 主要參考自蘋果的官方文件《The Swift Programming Language》,可以在這裡下載到