RxSwift之路 1#Swift語法知識準備

RxSwift之路 1#Swift語法知識準備

在開始學習 RxSwift 以前,必定要對 Swift 相關語法有所瞭解,不然就很難理解爲何能夠這樣。關於 Swift 的學習其實只要看看 Swift 的官方文檔就可夠了。我以前也列過一些學習資源:來自一線開發者的Swift學習資源推薦
如今開始進入正題。編程

Swift的優點

想一個有趣的問題,爲何沒有 RxObjc 呢?
實際上響應式的編程框架對語言仍是有些要求的,固然 OC 確實也有一個奠定式的 FRP 框架 ReactiveCocoa。可是客觀的說,在 Swift 裏響應式的框架寫起來會愉快的多,或者說更能發揮出語言的優點。
Swift 契合響應式有如下幾點:swift

  • 強類型,強類型的泛型
  • 靈活的閉包
  • 對併發模型的原生支持(Swift 5 的特性,還未發佈

Enum的關聯值和泛型

Swift 中的枚舉(Enum)能力相比 OC 能夠說獲得了昇華。再也不只是一個相似預編譯時的宏,而是一個完整的類型。和 Struct 同樣,能夠給他定義初始化方法,聲明函數,添加擴展。一樣的泛型一樣也試用於 Enum。
枚舉還有一項神奇的能力叫關聯值。一個枚舉能夠的值能夠是不一樣的類型。官方手冊裏的示例代碼以下:閉包

enum ServerResponse {
    case result(String, String)
    case failure(String)
}

let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")

switch success {
case let .result(sunrise, sunset):
    print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
    print("Failure...  \(message)")
}

每一個 case 能夠攜帶不一樣的類型,而且能夠不止是一個值。
當 Enum 結合泛型,就發生了有趣的事。直接貼代碼:併發

enum OptionalValue<Wrapped> {
    case none
    case some(Wrapped)
}

var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)
這就是 Swift 中的 Optional 實現的相似代碼。使用枚舉實現,表示值有兩種可能:沒有值的 .none 和是 Wrapped 類型的 .some。

有了以上的知識咱們再來看 Rx 中的事件流中的值Eventapp

public enum Event<Element> {
    /// Next element is produced.
    case next(Element)

    /// Sequence terminated with an error.
    case error(Swift.Error)

    /// Sequence completed successfully.
    case completed
}

每一次事件的值有三種可能:1.值(next),2.完成結束(completed),3.失敗(error)。框架

函數的默認參數

若是函數在聲明時設置了一個默認值,那麼在調用時這個參數就能夠不傳。
假設咱們給 Int 定義個擴展方法increment。若是不傳入值則默認加1,若是傳入就按照傳入的值增長:函數

extension Int {
    func increment(with number: Int = 1) -> Int {
        return self + number
    }
}
使用的時候 Xcode 就會提示兩個函數:


再也不須要像 OC 同樣定義幾個函數。
Rx 表示訂閱的subscribe函數,有時只要寫onNext,有時只要寫onError,就是由於這個函數在聲明時同時指定了默認參數:學習

extension ObservableType {

   public func subscribe(file: String = #file,line: UInt = #line,
                                          function: String = #function,
                                          onNext: ((E) -> Void)? = nil,
                                          onError: ((Swift.Error) -> Void)? = nil, 
                                          onCompleted: (() -> Void)? = nil,
                                          onDisposed: (() -> Void)? = nil)-> Disposable {
     // ...
    }

能夠看到這個函數爲訂閱每一個事件可能都聲明瞭默認參數,因此你在訂閱時能夠只訂閱本身關注的訂閱。優化

閉包

閉包的使用相似 OC 中的 block,具體使用就再也不介紹。提一下新手很容易忽略的語法糖。spa

閉包簡化語法

  • 閉包參數、返回值類型自動推斷
    由於 Swift 是強類型語言,閉包的參數的類型能夠推斷出來。好比以下代碼:
    reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
      return s1 > s2
    })
    s1 和 s2 的類型和返回值類型 Xcode 能夠推斷出來能夠省略:
    reversedNames = names.sorted(by: { (s1, s2)  in
      return s1 > s2
    })
  • 閉包表達式只有一行,能夠省略return
    由於只有一行,表達式執行的結果確定就是要返回的值,因此能夠省略。接上面的代碼能夠優化成這樣:
    reversedNames = names.sorted(by: { 
             (s1, s2)  in   s1 > s2
    })
  • 用$N代替參數
    有時實參的參數名沒什麼用,能夠直接用$N表明實參,$0表明第一個參數。上面的代碼進行這樣的簡化後就寫成了這樣:
    reversedNames = names.sorted(by:  { $0 > $1 })
  • 二元運算時能夠直接省略只用操做符表示
    當表達式只有一行時,二元運算的表達式能夠直接省略到只剩一個運算符,上面的能夠省略爲:
    reversedNames = names.sorted(by:  >)

尾閉包

當參數的最好一個參數是閉包時,能夠直接把最後一個閉包的實現跟在函數後面。
直接貼代碼表示:

// 一個最後一個參數是閉包的函數
func someFunctionThatTakesAClosure(closure: () -> Void) {
    // function body goes here
}

// 默認的調用方法
someFunctionThatTakesAClosure(closure: {
    // closure's body goes here
})

// 省略最後一個參數的方法名,而且把閉包的實現直接跟在函數後面
someFunctionThatTakesAClosure() {
    // trailing closure's body goes here
}
這種寫法簡化了代碼,讓代碼看起來更簡潔。

Rx 中的數據流操做符能夠靈活的組織閉包,常常會用到簡化的閉包的語法。

  Observable.of(1, 2, 3, 4, 5, 6)
    .filter { $0 % 2 == 0}
    .subscribe(onNext: {
      print($0)
})

剛開始的時候可能有點看不明白,慢慢的還原閉包的語法,以後看多了就會熟悉的。

相關文章
相關標籤/搜索