2

Consider the following two fragments of code:

scala> def f1(x:Any) = x match { case i:String => i; case _ => null }
f1: (x: Any)String

scala> def f2(x:Any) = x match { case i:Int => i; case _ => null }
f2: (x: Any)Any

Why is f2's return type Any, while f1's is String ? I was expecting either both to return Any or f2 to return Int.

Jus12
  • 17,824
  • 28
  • 99
  • 157

1 Answers1

12

The type inference chooses the lowest common supertype if a method returns different types.

Your function f1 returns a String or null, which common supertype is String because a String can have the value null. String is a subclass of AnyRef and AnyRefs can have null values.

Your function f2 return an Int (subclass of AnyVal) or null, which common supertype is Any. Int cannot be null.

See http://docs.scala-lang.org/tutorials/tour/unified-types.html for Scala´s class hierarchy.

Another example:

scala> def f3(b: Boolean) = if (b) 42
f: (b: Boolean)AnyVal

f3 returns

either 42 is b is true

or () if b is false.

So the types it returns are Int and Unit. The common supertype is AnyVal.

michael.kebe
  • 10,916
  • 3
  • 44
  • 62
  • Is there any rationale of not allowing `Int` to be `null`? I think it would have been more convenient if `null` was also a member of `AnyVal` (or if `Int` and other primitive types were instances of `Anyref`. – Jus12 Feb 28 '11 at 08:37
  • I think it is because the Scala compiler uses the primitiv data type (int, double, float, ...) of the JVM to get best performance. But I know exaclty. Have a look at this: http://stackoverflow.com/questions/2335319/what-are-the-relationships-between-any-anyval-anyref-object-and-how-do-they-ma – michael.kebe Feb 28 '11 at 09:18
  • 2
    @Jus12 The `AnyVal` classes are not references, so they can't be nullified. – Daniel C. Sobral Mar 01 '11 at 19:02