将RxJava Observable转换为RxScala Observable
我在Scala中编写了一个小型的JavaFx应用程序,我喜欢使用RxScala和RxJavaFx。用下面的代码,我收到了RxJavaObservable
:将RxJava Observable转换为RxScala Observable
JavaFxObservable.fromObservableValue(textfield.textProperty())
显然,正如我在斯卡拉写,我想有一个RxScalaObservable
来代替。现在我找到了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
,并为您隐式转换(如果您幸运的话!)。谷歌搜索这两个偏好,很显然,大多数人更喜欢JavaConverters
与asScala
关键字更明确的隐式转换。
问题2:有没有类似的结构像JavaConverters
与RxScala?这将使上面这么多清洁的代码,我会说:
import rx.lang.scala.JavaConverters._ // this class doesn't exist!
JavaFxObservable.fromObservableValue(textfield.textProperty())
.asScala
.map(s => /* do something */)
这个问题是RxScala项目this pull request的出发点。
原始问题中提出的语法可以通过导入rx.lang.scala.JavaConverters
来使用。
import rx.lang.scala.JavaConverters._
JavaFxObservable.fromObservableValue(textfield.textProperty())
.asScala
.map(s => /* do something */)
同样Scala的Observable
可以转化成使用asJava
一个Java Observable
。
另请参阅预期用途的examples。
我会写你的例子如下:
import rx.lang.scala.JavaConversions._
val texts: Observable[String] = JavaFxObservable.fromObservableValue(textfield.textProperty())
texts.map(s => /* do something */)
其中Observable[String]
是Scala的观测。 给予一个明确的类型为VAL texts
确保英寸
为什么没有asScala
隐式转换踢?
这就需要另一个隐含的包装类(让我们在PreScalaObservable
调用),只叫toScala
一个方法,所以,当你会写myJavaObservable.toScala
,编译器会变成类似toPreScalaObservable(myJavaObservable).toScala
。
有两个包装类会有点混乱。或者如果你非常聪明,你实际上可以将asScala
方法放到Scala Observable中,并像返回this
一样实现它,并且由于Java Observable没有方法叫做asScala
,所以myJavaObservable.toScala
可以工作。但是,对于初学者来说,这可能相当复杂......
但是,如果您有更好的主意,或者知道如何简单介绍这一点,我鼓励您在RxScala issues中打开一个问题;该项目仍然在0.x,没有什么是石头...... ;-)
为什么你需要将窗体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
我真的不明白你的意思!你在争论“*为什么RxScala与RxJava具有完全相同的功能?*”?我之所以要问如何在RxJava和RxScala之间进行转换,是因为Java的lambda表达式与2.11中的Scala的lambda表达式不匹配,并且在代码中具有一致性(在应用程序中无处不在)也是一件好事。也许你可以更多地解释一下你想说的“为什么要转换”和“从头开始”。 – RvanHeest
也许我不理解你,你使用JavaConverters是因为没有办法处理RXScala和JavaFxObservable相同吗?我建议使用RXScala,你可以做的和使用RxJava完全一样,所以不需要移植Java – paul
的任何代码啊,这就是你的意思。事实上,在这种情况下,我通过RxJavaFx来解决这个问题,RxJavaFx将JavaFx UI事件封装在一个'Observable'(它本身非常有用!)中,但我想到的是一个通用API,它为我提供了一个RxJava'Observable',需要将其转换为RxScala'Observable'。我完全承认RxScala本身就是RxJava库的Scala包装,但如果你在Scala编写的话,它有一些与RxScala更好的结合。例如,我之前提到的lambda的区别... – RvanHeest
说实话,我真的很喜欢所有运营商的链接。这是Rx API的定义权力之一(与Scala Collections API一样)。不得不引入额外的'val's,包括明确的输入,这并不是我特别喜欢在Scala中看到的东西。这是一个可行的把戏,这是一定的!我会进一步研究这个问题,并且肯定会考虑将这个讨论移到RxScala问题上。我想我可以在那边自己做拉请求。让我们继续坚持下去! – RvanHeest