I'm almost certain that this question has been asked before, but I'm missing the right words to find it.
scala> Seq[Any]( 3, 3.4 )
res0: Seq[Any] = List(3, 3.4)
scala> res0( 1 ).getClass
res1: Class[_] = class java.lang.Double
scala> Seq( 3, 3.4 )
res2: Seq[Double] = List(3.0, 3.4)
scala> res2( 1 ).getClass
res3: Class[Double] = double
Why is Scala handling my Double
input as java.lang.Double
within a Seq[Any]
but keeps it as scala.Double
when working with a Seq[AnyRef]
? Is there a way to prevent this behavior and instead always use the Scala types?
Scala's
Double
corresponds to Java'sdouble
but may get autoboxed and unboxed if needed and it becomesjava.lang.Double
when it gets autoboxed. In practice, collections require autoboxing of primitive variables.The types of collections you declare get inferred based on the value assigned to them if the type is not declared explicitly. The difference between the two declarations in the question is that for
Seq(value1,value2,...)
type inferrence tries to find the "best" type, comes up withSeq[Double]
and then intepretsvalue1
,value2
and so on based on this type (ScalaDouble
). If you declare the type explicitly asSeq[Any]
, type inferrence is not run (since you gave the type yourself) and so the valuesvalue1
,value2
etc. are not "forced" into being interpreted as being of a fixed type.Since
Seq
is a collection, primitives are not allowed and must be autoboxed, so Java'sdouble
can't fit in whilejava.lang.Double
can. The logic which tries to hide boxing and unboxing forSeq[Double]
and transparently interchanges the primitive and the object doesn't come into play. Actually, in aSeq[Any]
, each element may be of a different type which means such boxing and unboxing can't work in the general case (in your example,res0(0).getClass
is anInteger
in contrast tores2(0).getClass
which is a Double).So, essentially, if you don't declare the type explicitly, the type inferrence kicks in and first tries to find a common type for all elements of the collection and then casts all elements into that type while with the collection type parameter specified explicitly, no such thing takes place and all values' types are interpreted "raw".