Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

match tuple with null

I don't understand why the following case doesn't match. Null should be an instance of Any, but it doesn't match. Can someone explain what is going on?

val x = (2, null)
x match {
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v))
    case _ => println("catch all")
}

prints catch all

Thanks.

like image 317
agilefall Avatar asked Jan 08 '10 01:01

agilefall


4 Answers

This is exactly as specified.

Type patterns consist of types, type variables, and wildcards.
A type pattern T is of one of the following forms:

* A reference to a class C, p.C, or T#C.
This type pattern matches any non-null instance of the given class.

It's interesting that so much relevance has been attributed to null being a member of Any. It's a member of every type but AnyVal and Nothing.

like image 137
psp Avatar answered Oct 07 '22 21:10

psp


Have you tried the v placeholder for anything?

val x = (2, null)
x match {
    case (i:Int, v) => println("got tuple %s: %s".format(i, v))
    case _ => println("catch all")
}
like image 27
oxbow_lakes Avatar answered Oct 07 '22 20:10

oxbow_lakes


That's as specified (Scala Reference 2.7, section 8.2):

A reference to a class C, p.C, or T#C. This type patternmatches any non-null instance of the given class. Note that the prefix of the class, if it is given, is relevant for determining class instances. For instance, the pattern p.C matches only instances of classes C which were created with the path p as prefix.

like image 44
Daniel C. Sobral Avatar answered Oct 07 '22 20:10

Daniel C. Sobral


I'm just guessing here since I'm no scala expert but according to the documentation for the Any class in scala I'm thinking that since null isn't an object, it doesn't derive from Any and as such doesn't match the first listed case.

Adding the code sample below. It prints "something else" when run.

val x = (2, null)  
x match {  
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v))  
    case (i:Int, null) => println("something else %s".format(i))
    case _ => println("catch all")  
}  

After more research it seems like null should match with any sense the documentation says that it extends AnyRef which extends Any.

EDIT: Like everyone else has said. The first case doesn't match null on purpose. It's specified in the documentation.

like image 1
Brian Hasden Avatar answered Oct 07 '22 21:10

Brian Hasden