Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the NotNull trait work in 2.8 and does anyone actually use it?

trait NotNull {}

I've been trying to see how this trait can guarantee that something is not null and I can't figure it out:

def main(args: Array[String]) {
  val i = List(1, 2) 
  foo(i) //(*)
}

def foo(a: Any) = println(a.hashCode)

def foo(@NotNull a: Any) = println(a.hashCode) //compile error: trait NotNull is abstract

def foo(a: Any with NotNull) = println(a.hashCode) //compile error: type mismatch at (*)

And:

val i = new Object with NotNull //compile-error illegal inheritance

There is obviously some special compiler treatment going on because this compiles:

trait MyTrait {}

def main(args: Array[String]) {
  val i: MyTrait = null
  println(i)
}

Whereas this does not:

def main(args: Array[String]) {
  val i: NotNull = null //compile error: found Null(null) required NotNull
  println(i)
} 

EDIT: there's nothing about this I can find in programming in Scala

like image 704
oxbow_lakes Avatar asked Feb 25 '10 16:02

oxbow_lakes


2 Answers

NotNull is not yet finished. The intention is to evolve this into a usable way to check for non-nullness but it's not yet there. For the moment I would not use it. I have no concrete predictions when it will be done, only that it won't arrive for 2.8.0.

like image 148
Martin Odersky Avatar answered Sep 22 '22 04:09

Martin Odersky


Try and error:

scala> class A extends NotNull
defined class A

scala> val a : A = null
<console>:5: error: type mismatch;
 found   : Null(null)
 required: A
       val a : A = null
                   ^

scala> class B
defined class B

scala> val b : B = null
b: B = null

This works only with Scala 2.7.5:

scala> new Object with NotNull
res1: java.lang.Object with NotNull = $anon$1@39859

scala> val i = new Object with NotNull
i: java.lang.Object with NotNull = $anon$1@d39c9f

And the Scala Language Reference:

If that member has a type which conforms to scala.NotNull, the member’s valuemust be initialized to a value different from null, otherwise a scala.UnitializedError is thrown.

For every class type T such that T <: scala.AnyRef and not T <: scala.NotNull one has scala.Null <: T.

like image 21
Thomas Jung Avatar answered Sep 20 '22 04:09

Thomas Jung