2

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

JavaFxObservable.fromObservableValue(textfield.textProperty())

显然,当我使用 Scala 编写代码时,我希望使用RxScala Observable来代替。现在我找到了这个帖子,说我要么要导入隐式转换类,JavaConversions._要么直接调用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隐式地为您进行转换(如果您幸运的话!)。谷歌搜索这两者的偏好,很明显,大多数人更喜欢更显式的隐式转换 from JavaConverterswithasScala关键字进行更显式的隐式转换。

问题 2:是否有类似JavaConvertersRxScala 的构造?这将使上面的代码更加简洁,我想说:

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

3 回答 3

3

我会写你的例子如下:

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

这将需要另一个隐式包装类(让我们调用 in PreScalaObservable),只调用一个方法toScala,这样当您编写 时myJavaObservable.toScala,编译器会将其转换为类似toPreScalaObservable(myJavaObservable).toScala.

有两个包装类会有点混乱。或者,如果您非常聪明,您实际上可以将该asScala方法放入 Scala Observable 中并像 return 一样实现它this,并且由于 Java Observable 没有调用方法asScala,所以myJavaObservable.toScala可以工作。但同样,这对于初学者来说可能非常复杂......

但是,如果你有更好的想法,或者知道如何简单地呈现这个,我鼓励你在RxScala 问题中打开一个问题;该项目仍处于 0.x 中,没有什么是一成不变的...... ;-)

于 2016-09-15T20:16:16.367 回答
0

为什么需要将 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))
  }

平面图:

  @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

于 2016-09-23T07:56:02.287 回答
0

这个问题是这个RxScala 项目的拉取请求的起点。

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

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

同样,ScalaObservable可以Observable使用asJava.

另请参阅预期用途示例

于 2016-09-29T17:57:03.853 回答