Table of contents


無廢話swift

  • let : 宣告常數
  • var : 宣告變數
  • \() : string substitution,也就是在字數裡可以直接使用變數
  • dict = [:] : 宣告 dictionary 資料結構
  • ? : optional value (?加在型別後面,ex var foo: String?)
  • ! : implicitly unwrapped optionals,用來確定 optional 一定是有值的(非nil)
  • if let : Optional Binding語法,判斷條件不是null後指派值
  • .. : 範圍,不含最後一個
  • ... : 範圍,含最後一個
  • tuple : 可以取過屬性取得內容,也可以透過index取得內容 myTuple.foo, myTuple.bar, myTuple.1
  • Int... : variable arugment
  • setter 的參數名稱為newValue, 另外還有willSet跟didGet兩個method
  • switch 的對象可以是object ex: button`

switch用法比較特別

let vegetable = "red pepper"
switch vegetable {
case "celery":
    let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
    let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
    let vegetableComment = "Is it a spicy \(x)?"
default:
    let vegetableComment = "Everything tastes good in soup."
}

Optionals

變數名稱後面接了?表示對變數做Optional的Warpper,要unwarp optional變數有兩種方式

  1. ! : 強制unwrap,但必須確定該變數不是nil,不然會 runtime exception
  2. if let 語法會對wraped的值做unwrap ,如果不是nil,就會指派unwarped後的值給新變數

Downcasting

  1. as ! 強制轉型至 sub class的型別, 轉型失敗會拋出 runtime exception
  2. as ? 轉型至 sub class的型別,, 轉型失敗會傳回 nil
  3. is 檢查型別

NSDictionary, NSArray

TBD

Function

funciton 是 first-class type, 所以像變數一樣被當作參數轉入,也可以當作傳回值

func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}

var increment = makeIncrementer() // call makeIncrementer() 不需要參數,但傳回值是 function型態的 increment
increment(7) // increment是function 型號,使用方式是傳入Int,然後返回Int (Int -> Int)

External Parameter Names

localParameterName 是給 function內使用的,而externalParameterName是給call這個function時使用的,一旦定義了External Parameter Name,那call func時,就要加上去

func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}

Shorthand External Parameter Names

如果 local parameter name 跟 external parameter name 一樣的話,可以用# 取代 external parameter name

func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
    for character in string {
        if character == characterToFind {
            return true
        }
    }
    return false
}

Closures

swift的 closure 鼓勵用以下的方式進行 closure 的簡化

  1. 從 context 對 parameter 跟 type 做 type infer
  2. 採用 implicit return
  3. shorthand argument names
  4. Trailing closure syntax

Closure Expression Syntax

{ (parameters) -> return type in
    statements
}
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

/// 傳統的 function 方式
func backward  (s1: String, s2: String) -> Bool {
    return s1 > s2
}

names.sort(backward)


/// function 直接換成 closure
/// `in` keyword 用來表示 closure 的 parameters 跟 return type 結束了, 而 closure body 開始了
names.sort({(s1: String, s2:String) -> Bool in
    return s1 > s2
})

/// 寫成一行
names.sort({(s1: String, s2:String) -> Bool in return s1 > s2 })

/// `(s1: String, s2:String)`的 argument type 可由 names 的型別推斷出來
names.sort({ (s1, s2) -> Bool in return s1 > s2 })

/// return 可以拿掉
names.sort({ (s1, s2) in s1 > s2 })

/// parameter 的括號可以拿掉
names.sort({ s1, s2 in s1 > s2 })

/// swift closure 的 parameters 可以用 $0, $1, $2, ... 表示第1, 第2, 第3, ... 個 parameter
names.sort({ $0 > $1 })

/// Trailing Closure 的版本
names.sort() { $0 > $1 }

/// swfit 的 Operator Function `>` 是二元運算子, 一定是帶入兩個 parameters, 所以 `$0`,`$1` 可以拿到
names.sort(>)

Extensions

  • 加入計算屬性,但不能加入一般屬性(stored properties)
  • 定義 method
  • 提供新的 initializers
  • 定義 subscripts
  • 定義或使用新的 nexted types
  • conform a protocol
  • 可以加入新功能但是無法改寫既有的功能

當有類型轉換或者是初始化的需求時可以考慮使用 extensions

Initialization

Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.

Interactive Learning Document Format

Interactive Learning Document Format

The Swift Programming Language 下載的GuidedTour.playground, 在Xcode打開後,看起來像是一般的文件,但裡面的程式範例是可以修改的,修改後可以立即看到執行結果。 其實這是apple的Interactive Learning Document Format的文件格式,抓下來的GuidedTour.playground實際上是一個目錄, 裡面可包含html檔跟swift檔,然後用一個xml格式(contents.xcplayground)組織起來,就可以看到一份互動式文件了。Xcode處理這類型的文件時,html的部份就正常render成一般文件 ,swift的code,就視同一般的playgroud的程式處理。

protocol

swift的protocol中的所有method都是要實作的,如果想要有optional的method,就要加上@objc

@objc protocol MyProtocol {
    
    func mandatoryMethod()

    optional func optionalMethod() // protocol前面加上`@objc` 後才能使用optional method
}

但是加了@objc後,struct跟enum就不能confirm object-c style的protocol了

Pattern Match

  • ~= 是 pattern match operator
  • 200..<300 ~= 250 這樣ok; 250 ~= 200..<300 這樣語法錯誤

Resource