具有不同类型的可变列表的 Scala 重载构造函数

Scala overload constructor with mutable List of different type

我正在尝试使用 Int 和 Long 的可变列表重载构造函数,它提到该方法已经定义。 我需要 updateListmutable.MutableList[Int]mutable.MutableList[Long]

object PercentileDistribution {
  def apply(updateList: mutable.MutableList[Int], percentileDistribution: PercentileDistribution): PercentileDistribution = {
    updateList.foreach { x =>
      percentileDistribution.update(x)
    }
    percentileDistribution
  }

  def apply(updateList: mutable.MutableList[Long], percentileDistribution: PercentileDistribution): PercentileDistribution = {
    updateList.foreach { x =>
      percentileDistribution.update(x)
    }
    percentileDistribution
  }
}

作为 scala 的新手,我遇到了一些问题,感谢您的帮助。

该错误显然与您的代码中发生的向上转换有关。 Int 可以表示为 Long,因此您基本上编写了相同的方法,其中一个方法参数是另一个应用方法参数的升级版本。

您可以简单地使用具有 MutableList[Long] 类型的应用方法并删除具有 Int 的方法。

按照官方 Scala 文档中的 documentation,您将对类型在 Scala 中的行为有一个很好的了解

错误指的是type erasure。另一个答案错误地指出它与转换有关(尽管类型擦除会导致 casting-related 问题)。

在 Scala REPL 会话中完成的快速示例:

scala> class Foo {
     |   def bar(list: List[Int]) = "ints"
     |   def bar(list: List[String]) = "strings"
     | }
<console>:12: error: double definition:
def bar(list: List[Int]): String at line 11 and
def bar(list: List[String]): String at line 12
have same type after erasure: (list: List)String
         def bar(list: List[String]) = "strings"
             ^

这里的消息是说两个 bar 方法在编译后的输出中都会有类似 def bar(list: List): String 的类型签名;类型擦除删除了 [Int][String] 参数,使这两种方法无法区分。如果您在 JVM 上编写 运行 代码,那将是您不得不忍受的烦恼。

我推荐的解决方法是通过名称区分方法,例如而不是 apply 你可以称它为 forIntsforLongs.

另请注意,类型擦除会导致另一个问题:

scala> List(1,2,3).isInstanceOf[List[String]]
<console>:11: warning: fruitless type test: a value of type List[Int] cannot also be a List[String] (the underlying of List[String]) (but still might match its erasure)
       List(1,2,3).isInstanceOf[List[String]]
                               ^
res5: Boolean = true

scala> List(1, 2, 3) match {
     |   case l: List[String] => l // you'd think this shouldn't match, but it does
     | }
<console>:12: warning: fruitless type test: a value of type List[Int] cannot also be a List[String] (the underlying of List[String]) (but still might match its erasure)
         case l: List[String] => l // you'd think this shouldn't match, but it does
                 ^
res2: List[Int] with List[String] = List(1, 2, 3)

scala> res2.head
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  ... 33 elided

由于在编译后的字节码中,List[Int]List[String]都只表示为List,运行时实际上无法区分两者,所以isInstanceOf 检查可能会提供错误的答案,可能会导致 ClassCastExceptions,因为它试图将 Int 视为 String.

在你的情况下你可能会逃脱它,因为将 Int 转换为 Long 是安全的,但最好完全避免未经检查的转换。