/ / RxJava in RxScala Observable konvertieren - rx-java, rx-scala, rx-javafx

Konvertieren Sie RxJava Observable in RxScala Observable - Rx-Java, Rx-Scala, Rx-Javafx

Ich schreibe eine kleine JavaFx-Anwendung in Scala und ich verwende gerne RxScala und RxJavaFx dafür. Mit dem folgenden Code bekomme ich ein RxJava Observable:

JavaFxObservable.fromObservableValue(textfield.textProperty())

Offensichtlich möchte ich, während ich in Scala schreibe, eine haben RxScala Observable stattdessen. Jetzt habe ich gefunden dieser Beitrag, dass ich entweder die implizite Konvertierungsklasse importieren muss JavaConversions._ oder anrufen toScalaObservable direkt. Aber die erste Option tut es nicht für mich und die zweite Option sieht irgendwie hässlich aus:

Option 1:

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

Dies funktioniert nicht, da RxJava eine map auch wenn der Typ des Arguments technisch anders ist.

Option 2:

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

Das funktioniert, aber sei ehrlich Leute, das sieht einfach echt schrecklich aus!

Frage 1: Fehle ich etwas oder sind das wirklich die einzigen beiden Möglichkeiten?

Ich meine, um von den Standard-Kollektionen von Java in die Kollektionen von Scala zu konvertieren (und umgekehrt), gibt es zwei Möglichkeiten: JavaConverters und JavaConversions. Ersteres führt ein Schlüsselwort ein asJava/asScala, während letzteres irgendwie äquivalent ist rx.lang.scala.JavaConversions und macht die Konvertierung für Sie implizit (wenn Sie "Glück haben!.) Googeln auf den Vorlieben dieser beiden, ist es klar, dass die meisten Menschen bevorzugen die explizite implizite Konvertierung von JavaConverters mit dem asScala Stichwort.

Frage 2: Gibt es eine ähnliche Konstruktion wie? JavaConverters mit RxScala? Dies würde den obigen Code so viel sauberer machen, würde ich sagen:

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

Antworten:

2 für die Antwort № 1

Ich würde dein Beispiel wie folgt schreiben:

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

woher Observable[String] ist die Scala Observable. Geben Sie einen expliziten Typ für das val ein texts stellt sicher, dass die implizite Konvertierung einsetzt.

Warum nicht asScala?

Dies würde eine weitere implizite Wrapper-Klasse erfordern (lasst uns anrufen) PreScalaObservable), mit nur einer Methode genannt toScala, so dass wenn du schreibst myJavaObservable.toScala, würde der Compiler es in etwas wie verwandeln toPreScalaObservable(myJavaObservable).toScala.

Mit zwei Wrapper-Klassen wäre ein bisschen verwirrend. Oder wenn du sehr schlau bist, könntest du das tatsächlich tun asScala Methode in die Scala Observable und implementiere sie genauso wie sie zurückkehrt thisund da das Java Observable keine Methode aufgerufen hat asScala, myJavaObservable.toScala würde funktionieren. Aber auch das könnte für Anfänger sehr komplex sein ...

Aber wenn Sie eine bessere Idee haben, oder wissen, wie man das einfach präsentiert, ermutige ich Sie, ein Problem in der RxScala-Probleme; das Projekt ist immer noch in 0.x und nichts ist in Stein gemeißelt ... ;-)


0 für die Antwort № 2

Warum musst du RXJava in RXScala umwandeln? RXScala hat die gleichen Funktionen wie RXJava. Zum Beispiel

POSTLEITZAHL:

  @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));
}

VERSCHMELZEN:

  @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))
}

Ich würde von vorne anfangen, um ehrlich zu dir zu sein. Wenn Sie sich mehr Betreiberbeispiele ansehen möchten https://github.com/politrons/reactiveScala


0 für die Antwort № 3

Diese Frage war der Ausgangspunkt von diese Pull-Anfrage auf dem RxScala-Projekt.

Die in der ursprünglichen Frage vorgeschlagene Syntax kann beim Importieren verwendet werden rx.lang.scala.JavaConverters.

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

Ebenso eine Scala Observable kann in ein Java umgewandelt werden Observable verwenden asJava.

Siehe auch die Beispiele von beabsichtigtem Gebrauch.