我以某种方式打破了Scala型安全

时间:2018-02-07 15:23:39

标签: scala type-safety

有人能解释一下我是如何创建一个错误类型的案例类的吗? Bellow工作表输出:

case class OptObj(os: Option[String], s: String)
//defined class OptObj

val osCrazy: Option[Any] = Option(Option(Option(1)))
//osCrazy: Option[Any] = Some(Some(Some(1)))

def anyOpt: Option[Any] = osCrazy
//anyOpt: Option[Any]

def getOpt[T]: Option[T] = anyOpt.map(_.asInstanceOf[T])
//getOpt: [T]=> Option[T]

val o = OptObj(getOpt[String], "It has the wrong type inside, but was built!") 
//o: OptObj = OptObj(Some(Some(Some(1))),It has the wrong type inside, but was built)

o == OptObj(None,"")
//res0: Boolean = false

o == o
//res1: Boolean = true

o.os
//res2: Option[String] = Some(Some(Some(1)))

o.os.get
//java.lang.ClassCastException: scala.Some cannot be cast to java.lang.String

中创建了错误类型的对象,不应该创建对象失败吗?当我尝试对os属性进行一些操作时,它就失败了。

1 个答案:

答案 0 :(得分:2)

Any.asInstanceOf的文档解释了您所看到的内容。缺点是代码由于类型擦除而编译。

  

请注意,在运行时强制转换的成功是以Scala的擦除语义为模。因此,表达式1.asInstanceOf[String]将在运行时抛出ClassCastException,而表达式List(1).asInstanceOf[List[String]]则不会。在后一个示例中,因为类型参数作为编译的一部分被删除,所以无法检查列表的内容是否是所请求的类型。