如何在Scala中进行拳击?

St.*_*rio 2 arrays casting scala

我试图了解Scala中的转换是如何工作的.这是一个例子:

object Main extends App {
    val ai: Array[Any] = Array(1, 2, 3, 4, 5, 6)
    val ar: Array[AnyRef] = ai.map(_.asInstanceOf[AnyRef])
}
Run Code Online (Sandbox Code Playgroud)

它工作正常.https://ideone.com/6PerTR

现在让我们重写如下:

object Main extends App {
    val ai: AnyRef = Array(1, 2, 3, 4, 5, 6)
    val ar: Array[AnyRef] = ai.asInstanceOf[Array[Any]].map(_.asInstanceOf[AnyRef])
}
Run Code Online (Sandbox Code Playgroud)

这是行不通的.它ClassCastException现在失败,现在https://ideone.com/JbOQbb.为什么?我觉得在这里添加演员阵容已经够了 为什么第一个例子有效?

如果我们先铸造AnyRef,如何使它在第二种情况下工作Array[Any]?如何在这里添加拳击?

UPD:我也尝试过:

object Main extends App {
    val ai: AnyRef = Array(1, 2, 3, 4, 5, 6)
    val aii: Array[Any] = ai.asInstanceOf[Array[Any]]
    val ar: Array[AnyRef] = aii.map(_.asInstanceOf[AnyRef])
}
Run Code Online (Sandbox Code Playgroud)

但得到ClassCastException https://ideone.com/ZcgT6x.它看起来与第一个例子非常相似.如何投aiiArray[AnyRef]的情况下?

And*_*kin 5

TL; DR:第一个代码片段起作用,因为在生成数组时已经发生了自动装箱.第二个片段不起作用,因为创建的数组是一个Array[Int].


即使Int是子类型Any,一种Array[Int]没有的一个亚型Array[Any].因此,当你写

scala> val ai: Array[Any] = Array(1, 2, 3, 4, 5, 6)
ai: Array[Any] = Array(1, 2, 3, 4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

这基本上相当于

val ai: Array[Any] = Array[Any](1, 2, 3, 4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

这样所有整数都已经装箱了.结果是:

scala> ai.getClass
res0: Class[_ <: Array[Any]] = class [Ljava.lang.Object;
Run Code Online (Sandbox Code Playgroud)

也就是说,从一开始你ai就是一个Array[Object]权利.

第二个片段的关键区别在于,即使Array[Int] 它不是子类型Array[Any],它肯定子类型AnyRef,因此不会发生自动装箱:

scala> val ai: AnyRef = Array(1, 2, 3, 4, 5, 6)
ai: AnyRef = Array(1, 2, 3, 4, 5, 6)

scala> ai.getClass
res2: Class[_ <: AnyRef] = class [I
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这AnyRef是一个int带有未装箱的整数的阵列.

如果您现在尝试将未装箱的int数组转换为an Array[Any],则会出现类强制转换异常.

您可以通过强制执行立即自动装箱来修复您的第二个示例,如下所示:

object Main extends App {
    val ai: AnyRef = Array[Any](1, 2, 3, 4, 5, 6)
    val ar: Array[AnyRef] = 
      ai.asInstanceOf[Array[Any]].map(_.asInstanceOf[AnyRef])
}
Run Code Online (Sandbox Code Playgroud)

或者您可以将数组转换为正确的类型,即Array[Int]:

object Main extends App {
    val ai: AnyRef = Array(1, 2, 3, 4, 5, 6)
    val ar: Array[AnyRef] =
      ai.asInstanceOf[Array[Int]].map(_.asInstanceOf[AnyRef])
}
Run Code Online (Sandbox Code Playgroud)

  • @DonBranson感谢您的回复,我希望质量逐渐好转:) (2认同)