Scala type restrictions and a common set of Java

I am trying to wrap an rxjava method timeout to make it available to scala .

Like many other methods, I tried this:

def timeout[U >: T](timeout: Duration, other: Observable[U]): Observable[U] = {
  val otherJava: rx.Observable[_ <: U] = other.asJavaObservable
  val thisJava:  rx.Observable[_ <: U] = this.asJavaObservable
  toScalaObservable[U](thisJava.timeout(timeout.length, timeout.unit, otherJava))
}

But I get the following error:

Observable.scala:1631: error: overloaded method value timeout with alternatives:
($1: Long,x$2: java.util.concurrent.TimeUnit,x$3: rx.Scheduler)rx.Observable[_$85] <and>
($1: Long,x$2: java.util.concurrent.TimeUnit,x$3: rx.Observable[_ <: _$85])rx.Observable[_$85]
cannot be applied to (Long, scala.concurrent.duration.TimeUnit, rx.Observable[_$84])
  toScalaObservable[U](thisJava.timeout(timeout.length, timeout.unit, otherJava))

Original java method:

public Observable<T> timeout(long timeout, TimeUnit timeUnit, Observable<? extends T> other) {
   return create(OperationTimeout.timeout(this, timeout, timeUnit, other));
}

I am not very familiar with either Java or Scala (and all type restrictions), but as far as I understand: both otherJavaare also of thisJavatype rx.Observable[U], so why don't they line up?

+4
source share
2 answers

Um, you're right about the variance issues of Java generics used by Scala. Release step by step.


Look at your implementation:

// does not compile (with your original error)
def timeout[U >: T](timeout: Duration, other: Observable[U]): Observable[U] = {
  val otherJava: rx.Observable[_ <: U] = other.asJavaObservable
  val thisJava:  rx.Observable[_ <: U] = this.asJavaObservable
  toScalaObservable[U](thisJava.timeout(timeout.length, timeout.unit, otherJava))
}

, , A thisJava (A <: U, thisJava rx.Observable[A]). timeout thisJava: rx.Observable[A] rx.Observable[_ <: A], rx.Observable[_ <: U]: , . !

, A U, thisJava rx.Observable[U], timeout rx.Observable[_ <: U], otherJava. :

// still does not compile, sadly
def timeout[U >: T](timeout: Duration, other: Observable[U]): Observable[U] = {
  val otherJava: rx.Observable[_ <: U] = other.asJavaObservable
  val thisJava:  rx.Observable[U] = this.asJavaObservable // variance error
  toScalaObservable[U](thisJava.timeout(timeout.length, timeout.unit, otherJava))
}

. java rx.Observable , java . Scala , .

, Scala, a rx.Observable[_ <: U] a rx.Observable[U], , , this.asJavaObservable a rx.Observable[_ <: U].


[*], rx.Observable<T> , :

// this compiles and *should* work
def timeout[U >: T](timeout: Duration, other: Observable[U]): Observable[U] = {
  val otherJava: rx.Observable[_ <: U] = other.asJavaObservable
  val thisJava = this.asJavaObservable.asInstanceOf[rx.Observable[U]]
  toScalaObservable[U](thisJava.timeout(timeout.length, timeout.unit, otherJava))
}

, Scala Java , .

, asJavaObservable a rx.Observable[T] _ <: T , , , , ...

[*] " "

+3

[ @gourlaysama, ]

@Aralo "MyType[_ <: T] MyType[T]" , , MyType . List, List[+A], rx.Observable, Java, , , .

@gourlaysama asJavaObservable rx.Observable[T] _ <: T , rx.lang.scala.Observable[T] " T -, T", rx.Observable[_ <: T] ( rx.Observable<? extends T>).

, Scala, , timeout Java "": , Java Observable, T . "" U, T, Scala, Java , "", . reduce (. ), onErrorReturn .

, , ( ), Observable<T>, Observable<? extends T> ( Java) , , Scala.

+2

All Articles