我几乎可以肯定以前有人问过这个问题,但我找不到合适的词来找到它。
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
为什么 Scala 将我的 Double
输入处理为 Seq[Any]
中的 java.lang.Double
但将其保持为 scala.Double
在使用 Seq[AnyRef]
时?有没有办法阻止这种行为,而是始终使用 Scala 类型?
最佳答案
Scala 的 Double
对应于 Java 的 double
但如果需要可能会自动装箱和拆箱,当它自动装箱时它会变成 java.lang.Double
.实际上,集合需要自动装箱原始变量。
如果未明确声明类型,则根据分配给它们的值推断您声明的集合类型。问题中两个声明之间的区别在于,对于 Seq(value1,value2,...)
类型推断试图找到“最佳”类型,出现 Seq[Double]
然后基于此类型 (Scala Double
) 解释 value1
、value2
等。如果您将类型显式声明为 Seq[Any]
,则不会运行类型推断(因为您自己指定了类型),因此值 value1
、value2
等不会被“强制”解释为固定类型。
由于 Seq
是一个集合,原始类型是不允许的,必须自动装箱,所以 Java 的 double
不能放入 while java.lang.Double
可以。试图隐藏 Seq[Double]
的装箱和拆箱并透明地交换原语和对象的逻辑没有发挥作用。实际上,在 Seq[Any]
中,每个元素可能属于不同类型,这意味着这种装箱和拆箱在一般情况下不起作用(在您的示例中,res0(0) .getClass
是一个 Integer
,而 res2(0).getClass
是一个 Double。
因此,从本质上讲,如果您没有显式声明类型,类型推断就会开始并首先尝试为集合的所有元素找到一个通用类型,然后使用集合类型参数将所有元素转换为该类型明确指定,不会发生这样的事情,所有值的类型都被解释为“原始”。
关于java - 为什么 Scala 偶尔会回退到 Java 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18473877/