In response to my question How to develop macro to short-circuit null? someone pointed me to an earlier long thread with many answers, the most compelling of which to was https://stackoverflow.com/a/5569905 . But it doesn't quite work with Scala AnyVal "primitives" like Int:
object TestOp {
class SafeDereference[A](obj: A) {
def ?[B >: Null](function: A => B): B = if (obj == null) null else function(obj)
}
implicit def safeDereference[A](obj: A) = new SafeDereference(obj)
class C {
def getValue: Int = 0
}
def main(args: Array[String]) {
val c = new C
val x:Int = c ? (_.getValue)
}
}
gives a compilation error of:
[error] TestOp.scala:14: type mismatch;
[error] found : Any
[error] required: Int
[error] val x:Int = c ? (_.getValue)
[error] ^
[error] one error found
[error] {file:/home/mmalak/streaming-demo/}default-ae36bd/compile:compile: Compilation failed
A workaround is to replace val x:Int with val x:java.lang.Integer, and that will compile. Is there a way to improve SafeDereference above so that val x:Int is allowed?
Additional information
The following produces the desired output. The question now becomes how to move the typecasts into SafeDereference, and how to handle all the other Scala "primitives" (Boolean etc).
object TestOp {
class SafeDereference[A](obj: A) {
def ?[B >: Null](function: A => B): B = if (obj == null) null else function(obj)
}
implicit def safeDereference[A](obj: A) = new SafeDereference(obj)
class C {
def getValue: Int = 0
}
def main(args: Array[String]) {
val c:C = null
val x = (c ? (_.getValue)).asInstanceOf[java.lang.Integer].asInstanceOf[Int]
println("x="+x)
}
}
outputs, as desired:
x=0