问题
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
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/2335496/how-does-the-notnull-trait-work-in-2-8-and-does-anyone-actually-use-it