- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Null is a subclass of AnyRef... isn't it?
Mon, 2009-06-15, 11:59
Hi all,
I'm seeing strange (to me) behaviour with type bounds and null.
def doStuff[T <: AnyRef]() {
var t: T = null // compile error here
println(t)
}
...doesn't compile (2.7.4)— “type mismatch; found : Null(null)
required: T”. Whereas, as I understand it, I'm saying that the array
must be an array of reference type, and any reference type value may
be null... The following DOES compile:
def doStuff[T >: Null]() {
val t: T = null
println(t)
}
Now that's actually 'better' code in that the type bound is more
explicit about what I require of the type, but I thought that the
first one should work.
What say you?
Is it a consequence of the fact that trait NotNull extends AnyRef too…?
--Andrew
Mon, 2009-06-15, 12:17
#2
Re: Null is a subclass of AnyRef... isn't it?
On Mon, Jun 15, 2009 at 12:59 PM, Andrew Forrest wrote:
> Hi all,
>
> I'm seeing strange (to me) behaviour with type bounds and null.
>
> def doStuff[T <: AnyRef]() {
> var t: T = null // compile error here
> println(t)
> }
>
> ...doesn't compile (2.7.4)— “type mismatch; found : Null(null) required:
> T”. Whereas, as I understand it, I'm saying that the array must be an array
> of reference type, and any reference type value may be null... The following
> DOES compile:
>
> def doStuff[T >: Null]() {
> val t: T = null
> println(t)
> }
>
> Now that's actually 'better' code in that the type bound is more explicit
> about what I require of the type, but I thought that the first one should
> work.
>
> What say you?
>
Null is a subtype of any class or trait that inherits of AnyRef. But
it's not automatically a subtype of a type parameter that's bounded by
an AnyRef. So the behavior you are seeing is as expected.
Cheers
Mon, 2009-06-15, 14:57
#3
Re: Null is a subclass of AnyRef... isn't it?
On Mon, Jun 15, 2009 at 3:59 AM, Andrew Forrest <andrew [at] dysphoria [dot] net> wrote:
Hi all,
I'm seeing strange (to me) behaviour with type bounds and null.
def doStuff[T <: AnyRef]() {
var t: T = null // compile error here
println(t)
}
Null is not a subtype of Nothing.
Has anybody else noticed that Scala makes you speak in double negatives?
Mon, 2009-06-15, 16:07
#4
Re: Null is a subclass of AnyRef... isn't it?
All other answers are correct, and you couldn't find more knowledgeable persons to do it. But since I found the answers a bit too indirect, I'll give you mine, which is imprecise (or, strictly speaking, incorrect :), but might be easier to understand on a practical level.
Nothing is a subtype of everything, and null is not a valid value o Nothing. So if you get AnyRef, you could assign null to it, but if you get Nothing, you can't.
By the way, you can pass "null" as value o "Any".
On Mon, Jun 15, 2009 at 7:59 AM, Andrew Forrest <andrew [at] dysphoria [dot] net> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Hi all,
I'm seeing strange (to me) behaviour with type bounds and null.
def doStuff[T <: AnyRef]() {
var t: T = null // compile error here
println(t)
}
...doesn't compile (2.7.4)— “type mismatch; found : Null(null) required: T”. Whereas, as I understand it, I'm saying that the array must be an array of reference type, and any reference type value may be null... The following DOES compile:
def doStuff[T >: Null]() {
val t: T = null
println(t)
}
Now that's actually 'better' code in that the type bound is more explicit about what I require of the type, but I thought that the first one should work.
What say you?
Is it a consequence of the fact that trait NotNull extends AnyRef too…?
--Andrew
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Mon, 2009-06-15, 20:57
#5
Re: Null is a subclass of AnyRef... isn't it?
Cool, thanks everybody.
On 15 Jun 2009, at 15:58, Daniel Sobral wrote:
On 15 Jun 2009, at 15:58, Daniel Sobral wrote:
All other answers are correct, and you couldn't find more knowledgeable persons to do it. But since I found the answers a bit too indirect, I'll give you mine, which is imprecise (or, strictly speaking, incorrect :), but might be easier to understand on a practical level. Nothing is a subtype of everything, and null is not a valid value o Nothing. So if you get AnyRef, you could assign null to it, but if you get Nothing, you can't. By the way, you can pass "null" as value o "Any". On Mon, Jun 15, 2009 at 7:59 AM, Andrew Forrest <andrew [at] dysphoria [dot] net> wrote:
Hi all,
I'm seeing strange (to me) behaviour with type bounds and null.
def doStuff[T <: AnyRef]() {
var t: T = null // compile error here
println(t)
}
...doesn't compile (2.7.4)— “type mismatch; found : Null(null) required: T”. Whereas, as I understand it, I'm saying that the array must be an array of reference type, and any reference type value may be null... The following DOES compile:
def doStuff[T >: Null]() {
val t: T = null
println(t)
}
Now that's actually 'better' code in that the type bound is more explicit about what I require of the type, but I thought that the first one should work.
What say you?
Is it a consequence of the fact that trait NotNull extends AnyRef too…?
--Andrew
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
2009/6/15 Andrew Forrest :
> Hi all,
>
> I'm seeing strange (to me) behaviour with type bounds and null.
>
> def doStuff[T <: AnyRef]() {
> var t: T = null // compile error here
> println(t)
> }
>
> ...doesn't compile (2.7.4)— “type mismatch; found : Null(null) required:
> T”. Whereas, as I understand it, I'm saying that the array must be an array
> of reference type, and any reference type value may be null... The following
> DOES compile:
>
> def doStuff[T >: Null]() {
> val t: T = null
> println(t)
> }
>
> Now that's actually 'better' code in that the type bound is more explicit
> about what I require of the type, but I thought that the first one should
> work.
>
> What say you?
>
> Is it a consequence of the fact that trait NotNull extends AnyRef too…?
Null is a subtype of AnyRef, but it doesn't follow that it's a subtype
of everything which is a subtype of AnyRef (example: String is a
subtype of AnyRef, but it doesn't follow from that that String is a
Subtype of Map).
NotNull is one reason for this, but a more fundamental one is that
Nothing <: AnyRef but Null is not a subtype of Nothing (Nothing is the
type which has no values - the only way a method can have return type
Nothing is to never return normally. If Null <: Nothing then null
would be a value of type Nothing, which is not permitted)