将 RxJava 可观察对象转换为 RxScala 可观察对象

Convert RxJava Observable to RxScala Observable

我正在用 Scala 编写一个小型 JavaFx 应用程序,我喜欢为此使用 RxScala 和 RxJavaFx。使用以下代码,我得到 RxJava Observable:

JavaFxObservable.fromObservableValue(textfield.textProperty())

显然,当我在 Scala 中编写时,我想要一个 RxScala Observable 来代替。现在发现,说要么导入隐式转换classJavaConversions._,要么直接调用toScalaObservable。但是,第一个选项不适合我,第二个选项看起来有点丑陋:

选项 1:

import rx.lang.scala.JavaConversions._
JavaFxObservable.fromObservableValue(textfield.textProperty())
  .map(s => /* do something */)

这是行不通的,因为 RxJava 也提供了一个 map 运算符,尽管参数的类型在技术上是不同的。

选项 2:

import rx.lang.scala.JavaConversions._
toScalaObservable(JavaFxObservable.fromObservableValue(textfield.textProperty()))
  .map(s => /* do something */)

这很管用,但老实说,这看起来真的很糟糕!

问题 1:我是不是遗漏了什么,还是只有这两个选项?

我的意思是,要将 Java 的标准集合转换为 Scala 的集合(反之亦然),您有两个选择:JavaConvertersJavaConversions。前者引入关键字 asJava/asScala,而后者相当于 rx.lang.scala.JavaConversions 并隐式为您进行转换(如果您幸运的话!)。谷歌搜索这两者的偏好,很明显大多数人更喜欢使用 asScala 关键字从 JavaConverters 进行更显式的隐式转换。

问题2:RxScala有类似JavaConverters的构造吗?这将使上面的代码更加清晰,我会说:

import rx.lang.scala.JavaConverters._ // this class doesn't exist!
JavaFxObservable.fromObservableValue(textfield.textProperty())
  .asScala
  .map(s => /* do something */)

我会把你的例子写成如下:

import rx.lang.scala.JavaConversions._
val texts: Observable[String] = JavaFxObservable.fromObservableValue(textfield.textProperty())
texts.map(s => /* do something */)

其中 Observable[String] 是 Scala Observable。 为 val texts 提供显式类型确保隐式转换开始。

为什么没有asScala

这将需要另一个隐式包装器 class(让我们调用 PreScalaObservable),只有一个方法称为 toScala,因此当您编写 myJavaObservable.toScala , 编译器会把它变成类似 toPreScalaObservable(myJavaObservable).toScala.

的东西

有两个包装器 classes 会有点混乱。或者,如果你很聪明,你实际上可以将 asScala 方法放入 Scala Observable 并像返回 this 一样实现它,并且由于 Java Observable 没有名为 [= 的方法13=], myJavaObservable.toScala 可以。但是同样,这对于初学者来说可能相当复杂......

但是,如果您有更好的想法,或者知道如何简单地表达这一点,我鼓励您在 RxScala issues 中提出一个问题;该项目仍在 0.x 中,没有任何事情是一成不变的...;-)

为什么需要将 RXJava 格式转换为 RXScala?RXScala 具有与 RXJava 相同的所有功能。 例如

邮编:

  @Test def zip(): Unit = {
    addHeader("Observable zip")
    Observable.just("hello")
      .zip(Observable.just(" scala"))
      .zip(Observable.just(" world!"))
      .map(s => s._1._1.concat(s._1._2).concat(s._2).toUpperCase)
      .subscribe(s => println(s));
  }

合并:

  @Test def merge(): Unit = {
    addHeader("Observable merge")
    Observable.just("hello")
      .merge(Observable.just(" scala"))
      .merge(Observable.just(" world!"))
      .reduce((s, s1) => s.concat(s1))
      .map(s => s.toUpperCase).subscribe(s => println(s))
  }

FLATMAP:

  @Test def flatMap(): Unit = {
    addHeader("Flat Map")
    val text = "number mutated in flatMap::"
    val list = getList
    Observable.from(list)
      .flatMap(n => Observable.just(n) //--> New pipeline
        .map(n => text.concat(String.valueOf(n))))
      .map(s => s.toUpperCase())
      .subscribe(s => println(s))
  }

老实说,我会从头开始。 如果您想查看更多运算符示例 https://github.com/politrons/reactiveScala

这个问题是 RxScala 项目 this pull request 的起点。

原始问题中提出的语法可以通过导入rx.lang.scala.JavaConverters来使用。

import rx.lang.scala.JavaConverters._
JavaFxObservable.fromObservableValue(textfield.textProperty())
  .asScala
  .map(s => /* do something */)

同样可以使用 asJava.

将 Scala Observable 转换为 Java Observable

另请参阅 examples 预期用途。