从Scala调用(重载)RxJava函数

时间:2016-04-14 12:23:53

标签: scala rx-java rx-scala

我想从Observable这样的数组中创建一个Observable

package rxtest

import concurrent._
import concurrent.ExecutionContext.Implicits.global

import rx.lang.scala._
import rx.lang.scala.JavaConversions._
import rx.lang.scala.schedulers._

object A extends App {
    val ps = Array.fill(3)(Promise[Int]())
    val os = ps map {
            p => Observable from p.future observeOn NewThreadScheduler()
        }
    val v = rx.Observable.merge(os map toJavaObservable)
}

此程序无法编译,因为Observable有多个重载方法都称为merge

[error] /home/xgp/work/rxtest/src/main/scala/rxtest/A.scala:15: overloaded method value merge with alternatives:
[error]   [T](x$1: Array[rx.Observable[_ <: T]])rx.Observable[T] <and>
[error]   [T](x$1: rx.Observable[_ <: rx.Observable[_ <: T]])rx.Observable[T] <and>
[error]   [T](x$1: Iterable[_ <: rx.Observable[_ <: T]])rx.Observable[T]
[error]  cannot be applied to (Array[rx.Observable[_ <: Int]])
[error]     val v = rx.Observable.merge(os map toJavaObservable)
[error]                           ^
[error] one error found

然后我想在另一个Java类的帮助下删除重载:

public class RxUtils {
    public final static <T> Observable<T> merge(Observable<? extends T>[] os) {
        return Observable.merge(os);
    }
}

Scala代码变为(此处仅列出了相关部分):

val ps = Array.fill(3)(Promise[Int]())
val os = ps map {
        p => Observable from p.future observeOn NewThreadScheduler()
    }
val v = RxUtils.merge(os map toJavaObservable)

该程序仍然无法编译:

[error] /home/xgp/work/rxtest/src/main/scala/rxtest/A.scala:17: no type parameters for method merge: (os: Array[rx.Observable[_ <: T]])rx.Observable[T] exist so that it can be applied to arguments (Array[rx.Observable[_ <: Int]])
[error]  --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error]  found   : Array[rx.Observable[_ <: Int]]
[error]  required: Array[rx.Observable[_ <: ?T]]
[error]     val v = RxUtils.merge(os map toJavaObservable)
[error]                     ^
[error] /home/xgp/work/rxtest/src/main/scala/rxtest/A.scala:17: type mismatch;
[error]  found   : Array[rx.Observable[_ <: Int]]
[error]  required: Array[rx.Observable[_ <: T]]
[error]     val v = RxUtils.merge(os map toJavaObservable)
[error]                              ^
[error] two errors found

我有三个问题:

  1. 如何在第一种情况下使用纯Scala调用merge方法?
  2. 为什么第二个程序不能编译?
  3. 如何调用Scala中上述merge类中的RxUtils方法?

1 个答案:

答案 0 :(得分:2)

我真的很困惑你在这里做的事情。为什么要混用rx.Observablerx.lang.scala.Observable。只需选择其中一个:如果您在Scala中工作,请选择后者;如果您正在编写Java代码,请选择前者!

我还想指出this page,它会比较两种Observable

关于您的第一个程序,如果我更正ps的类型为Array[Promise[Int]],那么os必须具有Array[Observable[Int]]类型。如果您想将所有这些内容合并为一个Observable,则可以按照上面的链接在左栏中搜索merge(Array<Observable<? extends T>>)。事实证明,您可以在Scala中将其写为Observable.from(os).flattenos.toObservable.flatten

关于第二个和第三个问题:我还没有真正检查过这个问题,但这可能与Java和Scala之间的协方差有关。可能会帮助类型系统提供一些额外的类型信息。但是我想,如果你只是保留Scala语言并按原样使用RxScala库,你将不必处理这样的问题。