• RxSwift之路 1#Swift语法知识准备


    RxSwift之路 1#Swift语法知识准备

    在开始学习 RxSwift 之前,一定要对 Swift 相关语法有所了解,否则就很难理解为什么可以这样。关于 Swift 的学习其实只要看看 Swift 的官方文档就可够了。我之前也列过一些学习资源:来自一线开发者的Swift学习资源推荐
    现在开始进入正题。

    Swift的优势

    想一个有趣的问题,为什么没有 RxObjc 呢?
    实际上响应式的编程框架对语言还是有些要求的,当然 OC 确实也有一个奠基式的 FRP 框架 ReactiveCocoa。但是客观的说,在 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 中的事件流中的值Event

    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,具体使用就不再介绍。提一下新手很容易忽略的语法糖。

    闭包简化语法

    • 闭包参数、返回值类型自动推断
      因为 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)
    })

    刚开始的时候可能有点看不明白,慢慢的还原闭包的语法,之后看多了就会熟悉的。

  • 相关阅读:
    spring boot 整合elasticsearch
    elasticsearch 高级查询
    elasticsearch 基本操作
    day9--回顾
    day9--多线程与多进程
    day9--paramiko模块
    day10--异步IO数据库队列缓存
    数据库连接池
    数据库事务的四大特性以及事务的隔离级别
    使用JDBC进行数据库的事务操作(2)
  • 原文地址:https://www.cnblogs.com/LiLihongqiang/p/7795534.html
Copyright © 2020-2023  润新知