I have a Java interface that looks roughly like this:
public interface Foo {
public <T> T bar();
}
I want to implement this interface in Scala, where all of my code uses Option. However, since the interface will be used by Java users, I want to return null instead of None. I tried the following:
class FooImpl extends Foo {
def bar[T](): T = {
val barOpt: Option[T] = getBar()
barOpt.orNull
}
}
This results in the following compile error:
Expression of type Null does not conform to expected type T
This makes sense, type T is unrestricted, it could be an Int or some other type that can't be null. No problem, just add T >: Null and you're done, right?
class FooImpl extends Foo {
def bar[T >: Null](): T = {
val barOpt: Option[T] = getBar()
barOpt.orNull
}
}
Nope, still no dice. Now you get a new compile error:
[error] method bar has incompatible type
It seems that you can't apply any restrictions to T and still implement that interface.
Next, I tried using asInstanceOf:
class FooImpl extends Foo {
def bar[](): T = {
val barOpt: Option[T] = getBar()
barOpt.orNull.asInstanceOf[T]
}
}
But that just gets one more error:
Cannot prove that Null <:< T.
Is there any way to make this work?
You could use getOrElse and cast to T:
scala> def test[T](t: T): T = { Option(t).getOrElse(null).asInstanceOf[T] }
test: [T](t: T)T
You could move ugly stuff to helper class:
implicit class Defaults[T](val o: Option[T]) extends AnyVal {
def orDefault(): T = o.getOrElse(null).asInstanceOf[T]
}
def test[T](t: T): T = { Option(t).orDefault }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With