Reputation: 379
For example:
abstract type
ClassSymbol >: Null <: Universe.TypeSymbol with Universe.ClassSymbolApi
This was found here. I realize there is a description of what this does, but I can't make sense of it from a syntax standpoint.
What's the purpose of Null? It looks like it might be some kind of default but I only surmise that because I only see this kind of syntax with types, and I think null can be something returns for type without your program breaking. this is an abstract type, but it doesn't have a parameter which you can specify later, so how does this work as an abstract type?
Upvotes: 1
Views: 118
Reputation: 167901
Null
is a type that specifies that something can be null
. It's not a supertype, strictly speaking, because you can't do anything with a null
except pass it around and check that, yep, it's still null
. In this way it's very much like Nothing
, except that you can't even get an instance of a Nothing
to pass around.
Now, one could say, "well, any AnyRef
could be null
", but then how do you think of the instance null
itself? null
can fill in for pretty much anything, which, as a type, means that it must be a subtype of everything that can be null
! And that's what Null
is: the subtype of everything that can be Null
.
Wait, wait, you say. You can't actually have a subtype of everything--that means that null
would have every possible functionality! If you think about it, null
does promise every type of functionality that any AnyRef
has--but they're all empty promises, and whenever you try to use that functionality you get a NullPointerException
instead.
Now, the question is, why make a type >: Null
(meaning that null
is a valid value for it) instead of <: AnyRef
which should imply the same thing?
Well, it turns out that Scala doesn't actually model things that way, to leave open the possibility that you could have an AnyRef
which you were absolutely sure could not ever possibly be null
. So asking for <: AnyRef
("I am a subclass of AnyRef") doesn't mean the same thing theoretically, even though in practice absolutely-not-null-AnyRef
s are not really implemented. (Also, Any
would get really awkward if Null
was not an explicit type.)
So type Foo >: Null <: Bar
just means that you explicitly admit that null
can fill in for instances of any possible type of Foo
, and thus you can write val foo: Foo = null
.
Upvotes: 5
Reputation: 14842
Consider the following:
trait Foo {
type A >: Null
def someA: A = null
}
In the above dummy trait, A
is an abstract type member with a type bound. This means: Whatever a subclass defines A
to be, Null
must be a subtype of it. (The opposite is also possible: A <: Bar
).
The main reason for doing is, is to make null
be a valid value for A
as can be seen in the second line. Without it, scalac would complain at the second line:
found : Null(null)
required: Foo.this.A
To your question what Null
is: It's the type of null
and it is a subtype of AnyRef
and all of its subtypes.
Upvotes: 3