我正在Scala中编写一个小型JavaFx应用程序,我喜欢使用RxScala和RxJavaFx。使用以下代码,我得到 RxJava Observable
:
JavaFxObservable.fromObservableValue(textfield.textProperty())
显然,正如我在Scala中写的那样,我希望有一个 RxScala Observable
。现在我找到了this post,说要么我必须导入隐式转换类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的集合(反之亦然),您有两个选项:JavaConverters
和JavaConversions
。前者引入了关键字asJava
/ asScala
,而后者有点等同于rx.lang.scala.JavaConversions
并且隐式地为您进行转换(如果您很幸运!)。通过Google搜索这两者的偏好,很明显大多数人更喜欢JavaConverters
与asScala
关键字的更明确的隐式转化。
问题2:是否有与JavaConverters
类似的结构与RxScala?这会使上面的代码更加清晰,我会说:
import rx.lang.scala.JavaConverters._ // this class doesn't exist!
JavaFxObservable.fromObservableValue(textfield.textProperty())
.asScala
.map(s => /* do something */)
答案 0 :(得分: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
?
这需要另一个隐式包装类(让我们在PreScalaObservable
中调用),只有一个名为toScala
的方法,所以当你编写myJavaObservable.toScala
时,编译器会把它转过来像toPreScalaObservable(myJavaObservable).toScala
这样的东西。
有两个包装类会有点混乱。或者如果你非常聪明,你实际上可以将asScala
方法放入Scala Observable并将其实现为返回this
,并且因为Java Observable没有名为asScala
的方法, myJavaObservable.toScala
会奏效。但同样,对于初学者而言,这可能相当复杂......
但如果你有更好的想法,或者知道如何简单地提出这个问题,我建议你在RxScala issues中提出一个问题。该项目仍然是0.x而且没有任何内容......; - )
答案 1 :(得分:0)
为什么需要将RXJava转换为RXScala ?, RXScala具有RXJava所具有的所有功能。 例如
ZIP:
@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));
}
MERGE:
@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
答案 2 :(得分:0)
这个问题是RxScala项目this pull request的起点。
可以通过导入rx.lang.scala.JavaConverters
来使用原始问题中提出的语法。
import rx.lang.scala.JavaConverters._
JavaFxObservable.fromObservableValue(textfield.textProperty())
.asScala
.map(s => /* do something */)
同样,可以使用Observable
将Scala Observable
转换为Java asJava
。
另请参阅预期用途的examples。