【问题标题】:Scala: I managed to wrap a String into an Option[Double]... is that a bug?Scala:我设法将一个字符串包装成一个 Option[Double] ......这是一个错误吗?
【发布时间】:2014-02-01 20:00:42
【问题描述】:

当我看到结果时,我简直不敢相信自己的眼睛......看看这段代码

object ScalaBug  {

  def main(args: Array[String]): Unit = {
    // This goes OK
    val aa: Option[Double] = first[Double]("A string in a Double!!") 
    println(aa)
    println(aa.getClass())
    aa match {
       // ...but this raises an error
       case Some(v) => println(v.getClass())
       case None => None
    }

    // The call to the other methods fails...
    val bb: Double = second[Double]("Yet another string in a Double!!") 
    println(bb)
    val cc: Option[Double] = third[Double]("One more string in a Double!!") 
    println(cc)

  }

  def first[T](x: String): Option[T] = Some(x.asInstanceOf[T])

  def second[T](x: String): T = x.asInstanceOf[T]

  def third[T](x: String): Option[T] = { val d = x.asInstanceOf[T] ; Some(d)}
}

看来这个bug是在调用Some()的构造方法:这里没有发生强制转换...

事实上,third 方法与 first 方法的作用相同,但在两个不同的步骤中,我得到了预期的错误。

我认为这应该被视为一个错误。但我想与各位专家分享我的观点。

为了清楚起见,我使用的是 scala 2.10.2,但我也使用了 scala 2.10.4-RC1

【问题讨论】:

  • 这不是错误。像这样使用asInstanceOf 几乎是在敲诈编译器,让他们相信不真实的东西。这个加号类型擦除=一团糟。
  • 所以我想应该避免使用 .asInstanceOf 方法......那么,什么是转换类型的更好方法?
  • 就像@ghik 所说,如果你明确地对编译器撒谎,你可以做各种愚蠢的事情。您应该能够使用显式转换 (T)x 在 Java 中编写几乎相同的代码,甚至可以在 Java 8 中使用新的 Optional 类型来代替 Scala 的 Option
  • @ghik:我很好奇——类型擦除与这样的转换有什么关系?
  • 这个问题读起来就像那些必须无法抗拒的互联网广告,因为它们不断出现:令人震惊!桑尼维尔家庭主妇美白牙齿的秘诀,奥巴马不想让你知道!

标签: scala classcastexception


【解决方案1】:

asInstanceOf 在泛型代码中只是向编译器保证你知道一件事实际上是另一件事。每当您摆脱通用代码并依赖这种行为时,虚假的承诺就会在您的脸上炸开。

这就是 JVM 的工作方式:您需要一个特定的类来测试 instanceof

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 2013-05-15
    • 2013-09-11
    • 2012-10-14
    • 2012-09-18
    相关资源
    最近更新 更多