2016年4月9日 星期六

玩玩 swift

swift 是開發 iOS 程式重要的語言工具之一, 目前是 open source,

官方網站:  https://swift.org/

首先在 linux 下需架好環境:

參考網址
https://swift.org/getting-started/#installing-swift
https://linuxmint.tumblr.com/post/135280204927/how-to-use-swift-programming-language-in-ubuntu


1.  swift 官方下載: https://swift.org/download/#releases
    https://swift.org/builds/development/ubuntu1510/swift-DEVELOPMENT-SNAPSHOT-2016-01-25-a/swift-DEVELOPMENT-SNAPSHOT-2016-01-25-a-ubuntu15.10.tar.gz.sig
https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-01-25-a/swift-DEVELOPMENT-SNAPSHOT-2016-01-25-a-ubuntu14.04.tar.gz
     p.s. 因 release 版未將 swift-build 放入, 最好下載上述開發版
2. 使用 tar 解出swift 套件:  tar -zxvf  xxxx-xxx.xz
3. 設定好環境變數 PATH 指向swift 編譯程式的 bin 目錄: export PATH= ....:$PATH
4. 安裝開發 swift 所需要的相關套件:   apt-get install clang   libicu-dev
5. 驗證是否安裝成功:  swift -version
6. swift 交談命令程式(REPL), 直接執行 swift 就可看到:  swift
     在 REPL 中鍵入 :q 離開 swift 交談視窗
7. 建立編譯環境
     a. 建立一個目錄當專案:  mkdir Hello
     b. 進入該專案目錄:  cd Hello
     c. 建立 Package.swift 檔案: touch Package.swift
     d. 建立原始碼目錄: mkdir Sources
     e. 建立原始碼主檔: touch Sources/main.swift
     f. 編輯主檔: gedit Source/main.swift
         將程式碼 print("Hello World") 鍵入主檔(main.swift)中
     g. 開始編譯: swift build

         編譯程式將 Source/main.swift 加以編譯程可執行檔,使用 Package.swift 所在的目錄名稱來命名可執行檔, 編譯好的執行檔將會放在 .build/debug 目錄內

     h. 執行編譯過的程式:      .build/debug/Hello

基礎知識:
常數宣告 let  a=...
變數宣告 var a=...

常數型別(TYPE)宣告   let a:TYPE=...
變數型別(TYPE)宣告  var a:TYPE=...
其中 TYPE 可以是: Int, Uint, Float, Double, String
(整數, 浮點數, 更精密浮點數, 字串)

許多型別, 其實swift 會自行推論出正確的型別,
例如 var a=1   ---> a 是整數
         var b="sasds"  --->  b 是字串
         var c=1.23       --->  c 是 Double
...等等, 因此上述的 a,b,c 其實不需宣告型別(TYPE) 也可以


何謂 Tuples: 將各種型別組合成一個集合, 例如 let a=("1",2,3.1415)
其中 a.0 等於字串 "1", a.1  等於整數 2, a.2 等於浮點數 3.1415
將Tuple 值用括號可以分離出各元素:
例如  let a=("1",2,3.1415);  let  (a0,_,a2)=a , 其中 a0="1", 第二個使用底線忽略, a2=3.1415

陣列型別使用相同型別的元素用 [,,] 來構成, 例如 let a=[1,2,3]
字典型別用key:value成對元素陣列所構成 let dic=["a":"dsd","2":"kiki"]; let b=dic["a"];
其中 key 與 value 型別必須分別統一使用相同型別  let dic=[1:"dsd",2:"kiki"]; let b=dic[1];

何謂 optionals (可有可無)變數, 例如宣告 var a:Int? =404, 其中後面 '?' 就已代表 a 宣告成可有可無的整數型別, 可有可無意味著:變數未指定也可, 此例 a=nil, 或已指定完, 此例 a=404
但不指定 optionals 的變數, 則不能付與 nil 值

當一個可有可無變數要強制取用其值時,可以再後面加上驚嘆號 '!',強制取用,但一旦此變數若未指定.則程式可能會當掉
因此可以透過 optional binding 敘述來檢查 , 避免錯誤
if let  constantname = someOptionalvalue {
//   ...
}

錯誤處理程式
func catThrowAnError() throws {
 // ..程式可能會丟出依些錯誤訊息
}


do {
          try catThrowAnError()
       
          // ... No error, continue
     }   catch  Error1.xxx {        
          // ...
     } catch  Error2.xxx {        
          // ...
      }
自訂驗證程序宣告, 當 condition 有錯誤時, 則停止程式, 並丟出錯誤訊息:
   assert(condition,"Error message");

字串可以相加  "Hello" + "World"
餘數  (a%b)
範圍 1...5     指的是 1 到 5
範圍 0..<10 指的是 0 到 9 ( 從0 開始, 小於 10)

the nil coalescing operator ??
let a:Int?=nil      // define an optional Interger constant, assign it to nil
// if a is not nil return a , else return 0
let b= ( a != nil ?  a!: 0 )
// same as expression    a ?? 0
let b=( a ?? 0 )

Type casting: 成型

字串的method
1. characters.count
2. append
3. insert

var a="SDSD"
a.characters.map {$0} // list all the character

單一字元(single character)並不等於單一字元的字串(a string with single character), 在於它是不同型別, 字元用 Character 來宣告, 字串用 String 來宣告, 使用前後雙引號時將自動判斷為字串型別

swift 語言有3種主要的收集型別(collection type): 陣列(Array),  集合(Set), 字典(Dictionary, 這些行別都是 mutable, 可修改的. 但若宣告程常數就不得修改了

在 swift 裡的條列式流程 switch .. case, 在case 執行完後將會自動跳離, 不像 c 語言要加入 bread 來跳開. 但可以用 fallthrough 讓它往下繼續執行, switch 可以用 tuple 當成多變數條件式, 如果無關係的條件, 可以用底線 '_' 讓它忽略該條件

switch (a,b) {
    case (_,0) :
                      ...
    case (0,_) :
                       ...
    default:
                       ...
}

value binding: 數值綁定
在switch-case 的條件式裡可以用 let 語法來綁定數值(value binding)讓他可以在該條件成立下取用,例如:
var a=(2,3)
// ...
 switch  a {
   case (let b,_) :
       print("\(b)")
   case (_,let c) :
       print("\(c)")
   default:
      print("OK")
 }

label: 標籤可以用名稱加帽號 lableName: 加註在程式迴圈上, 之後用 break lableName, 或 continue lableName 來控制程式流程, break lableName 用來結束迴圈內程序而跳到所標註迴圈外再往下執行. 而 continue lableName 除了放棄迴圈程序外, 並重新跳到所標註迴圈開頭地方再執行

guard  指令類似 if 的語法, 但 guide 必須要有 else 指令附加在後面, 而且他通常是用在func裏面,最後要有 return, 它預期條件式是對的,一旦不對才執行後面 else 內的指令,可以減少在對的條件成立時再寫指令
func my(b:Int) ->  {
     guard  b>3 else { print("OK"); return; }  
}
my(4)  // OK
my(3)  //

初始化消滅:當抽象型別像分類(class),結構(struc)及列舉(enum)要實體化成個體時, 他會執行該型別的的初始化程序叫 init(). 只有分類所產生的個體, 當要消滅時才會執行消滅程序叫作 deinit(), 對於儲存式屬性, 可以在型別宣告時就直接給初始值, 也可以透過初始化參數設定該屬性.初始化參數的語法與 func 裏面的參數語法是相同的. 對於常數型態的屬性仍然可以透過上述初始化程序重新設定它, 之後常數就不得再更改了. 對於分類所產生的個體而言, 常數屬性不能被子類別的繼承者所修改









沒有留言: