[英]how to use asInstanceOf properly in Scala
我一直在玩基本的Scala数据类型。 我注意到scala.Any
类定义方法asInstanceOf[T0]: T0
从这里 API有它可以“将接收器对象转换为T0类型”。 使用此方法作为起点,我想调查Scala中的强制转换。 另外,我查看了stackoverflow以获取有关此主题的其他问题,我想出了这个有了这些信息,我写了一个愚蠢的程序。
package com.att.scala
import com.att.scala.Sheltie
object Casting {
//def foo(x: String){
def foo(x: Int) {
println("x is " + x)
//if(x.isInstanceOf[String])
if(x.isInstanceOf[Int])
println("Int x is " + x)
//println("String x is " + x)
}
def entry() {
//val double: Any = 123.123
val double: Double = 123.23
val int = double.asInstanceOf[Int] //exception expected here
//val str: String = "123"
foo(int)
}
}
我的目标是了解在以下情况下会发生什么(以及为什么):1)从Any类型转换为Int。 2)从Double类型转换为Int 3)从String转换为Int
在第一种情况下,当我运行程序为 - com.att.scala.Casting.entry时,我得到了一个运行时ClasscastException,如下所示。 例外如下所示:
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source) at com.att.scala.Casting$.entry(Casting.scala:17)
在第二种情况下,我得到以下结果:int是123 x是123 Int x是123
在这种情况下,代码应该产生ClasscastException,但它不会。 这是我的担心。
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source) at com.att.scala.Casting$.entry(Casting.scala:20)
在这个例子中,我的目标是了解Scala中的基础知识。 我知道这个例子无论如何都不是一个现实世界的例子,但我试图让我的头脑缠绕在基础上。
Java(和Scala)允许您将原始double
为int
(在Scala的情况下, Double
到Int
)。 另一方面,您无法将java.lang.Double
为java.lang.Int
。
当你将Double
声明为Any
,你明确要求编译器忘记你给它一个Double
。 因此,为了支持Any
接口,编译器将值存储为boxed double(即java.lang.Double
)。
这种行为确实令人困惑,但这不是一个错误。 根据Scala语言规范 §12.1:
如果T是数值类型(第12.2节),则特别处理测试x.asInstanceOf [T]。 在这种情况下,强制转换将转换为转换方法x.toT(第12.2.1节)的应用程序。
我认为你混淆了“演员”和“转换”这两个词。
标准的转换方法开始to
,例如20d.toInt
将转换值20
型Double
类型的值20 Int
。
另一方面, asInstanceOf
是一种特殊类型的铸造方法。 它只是通知编译器该值是其参数中指定的类型,如果在运行时期间调用此方法的值与您在type参数中指定的值不匹配,则会抛出异常。 即a.asInstanceOf[B]
所提供的价值a
必须是一个类型的B
或继承它-否则,你会得到一个例外。
刚做了更多的测试(编译和运行),我想这可能是来自asInstanceOf的一个bug,它不会进行强制转换。
最后一行命令给我编译错误:
警告:(46,38)无结果类型测试:Int类型的值也不能是S println(listTemp2(1).isInstanceOf [S])//将无法编译
^
val listOfS = Some(List(S("i1", "k1", "s1"), S("i2", "k2", "s2")))
val listTemp:Seq[K] = listOfS.get.asInstanceOf[Seq[K]]
val listTemp2:Seq[Int] = listOfS.get.asInstanceOf[Seq[Int]]
println("ListTemp:")
println(listTemp(1)) //print S(i2,k2,s2)
println(listTemp(1).isInstanceOf[S]) // true
println(listTemp(1).isInstanceOf[K]) // false
println(listTemp2(1)) //print S(i2,k2,s2)
println(listTemp2(1).isInstanceOf[Int]) // false
println(listTemp2(1).isInstanceOf[S]) // won't compile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.