【问题标题】:RxSwift unwrap optional handy function?RxSwift 解开可选的便捷功能?
【发布时间】:2016-04-19 05:41:16
【问题描述】:

目前我创建了一个函数unwrapOptional 来安全地解开流中的可选输入。

    func unwrapOptional<T>(x: Optional<T>) -> Observable<T> {
       return x.map(Observable.just) ?? Observable.empty()
    }

    let aOpt: String? = "aOpt"
    _ = Observable.of(aOpt).flatMap(unwrapOptional).subscribeNext { x in print(x)}

    let aNil: String? = nil
    _ = Observable.of(aNil).flatMap(unwrapOptional).subscribeNext { x in print(x)}

    let a: String = "a"
    _ = Observable.of(a).flatMap(unwrapOptional).subscribeNext { x in print(x)}

   // output 
    aOpt
    a

我要归档的是创建一个方便的函数,而不是使用flatMap(unwrapOptional),例如

Observable.of(a).unwrapOptional()

我试图做的事情,但它永远不会编译......

extension ObservableType {
    func unwrapOptional<O : ObservableConvertibleType>() -> RxSwift.Observable<O.E> {
        return self.flatMap(unwrapOptional)
    }
}

【问题讨论】:

    标签: swift rx-swift


    【解决方案1】:

    您希望unwrapOptional 方法仅适用于具有可选类型的可观察对象。

    所以你必须以某种方式约束ObservableElement 以符合Optional 协议。

    extension Observable where Element: OptionalType {
        /// Returns an Observable where the nil values from the original Observable are
        /// skipped
        func unwrappedOptional() -> Observable<Element.Wrapped> {
            return self.filter { $0.asOptional != nil }.map { $0.asOptional! }
        }
    }
    

    不幸的是,Swift 没有定义这样的协议 (OptionalType)。所以你也需要自己定义

    /// Represent an optional value
    ///
    /// This is needed to restrict our Observable extension to Observable that generate
    /// .Next events with Optional payload
    protocol OptionalType {
        associatedtype Wrapped
        var asOptional:  Wrapped? { get }
    }
    
    /// Implementation of the OptionalType protocol by the Optional type
    extension Optional: OptionalType {
        var asOptional: Wrapped? { return self }
    }
    

    【讨论】:

      【解决方案2】:

      结帐unwraphttps://github.com/RxSwiftCommunity/RxSwift-Ext :)

      https://github.com/RxSwiftCommunity/RxOptional

      现在,您应该使用 RxOptional 来满足您的个人需求
      但是,RxSwift-Ext 将在未来 2-3 个月内呈指数级增长 :)

      【讨论】:

        【解决方案3】:

        RxSwift 现在支持compactMap()。因此,现在您可以执行以下操作:

        func unwrap(_ a: Observable<Int?>) -> Observable<Int> {
          return a.compactMap { $0 }
        }
        

        【讨论】:

          【解决方案4】:

          这是一个不需要OptionalType的版本(来自https://stackoverflow.com/a/36788483/13000

          extension Observable {
          
              /// Returns an `Observable` where the nil values from the original `Observable` are skipped
              func unwrap<T>() -> Observable<T> where Element == T? {
                  self
                      .filter { $0 != nil }
                      .map { $0! }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2023-03-23
            • 2012-04-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-05-13
            • 1970-01-01
            • 2012-09-09
            相关资源
            最近更新 更多