scala - Scala父类(super class)构造函数中的“Too many arguments”错误,但在REPL中不存在

标签 scala constructor compiler-errors

我正在编写一个类,它使用一些自定义构造函数逻辑扩展了Scala的不可变映射。举一个简单的例子,说我想要一个整数到字符串的映射,该字符串初始化为1 -> "one", 2 -> "two"。在REPL中,我可以编写以下内容。

scala> import collection.immutable.HashMap
import collection.immutable.HashMap

scala> HashMap[Int, String](1->"one", 2->"two")
res0: scala.collection.immutable.HashMap[Int,String] = Map(1 -> one, 2 -> two)

在我的程序中,我想使用相同的构造函数调用,但是当我尝试将其放入类定义行时,出现“构造函数参数过多”错误。
scala> class MyMap extends HashMap[Int, String](1->"1", 2->"2")
<console>:8: error: too many arguments for constructor HashMap: ()scala.collection.immutable.HashMap[Int,String]
   class MyMap extends HashMap[Int, String](1->"1", 2->"2")
               ^

鉴于调用父类(super class)构造函数的方式是在类定义中,我认为在REPL中创建HashMap的任何表达式也应在定义中起作用,但是我在这里缺少一些细微之处。

(我认为扩展具体的类HashMap而不是特征是正确的做法,因为我想使用默认的 map 实现。扩展HashMap是我在Java中要做的事情,但我不确定100%地认为扩展具体的收集类是最Scalaesque的操作方式。)

因为我希望MyMap是不可变的,所以我需要在构造函数时指定初始值。我可以尝试在伴随对象的apply函数内部进行初始化,如下所示:
class MyMap extends HashMap[Int, String]

object MyMap {
  def apply() = new MyMap ++ List(1 -> "one", 2 -> "two")
}

但是MyMap()返回一个不变的映射,而不是MyMap

初始化MyMap的正确方法是什么?

该链接about implementing Map with concrete types是相关的。

最佳答案

您在这里遇到错误,因为在编写Map()时,您没有调用Map的构造函数。取而代之的是,调用它的伴随对象的apply方法(或更精确地说,是其父类(super class)之一的apply方法。请参见om-nom-noms注释):

scala> Map(1 -> "one")
res0: scala.collection.immutable.Map[Int,String] = Map(1 -> one)

scala> Map.apply(1 -> "one")
res1: scala.collection.immutable.Map[Int,String] = Map(1 -> one)

如果要拥有自己的Map实现,则需要创建自己的实现。我想到的最简单的事情是:
object MyMap {
  def apply(ts: (Int, String)*): MyMap[Int, String] = new MyMap(ts.toMap)
  def apply(): MyMap[Int, String] = apply(1 -> "one", 2 -> "two")
}

class MyMap[A, B] private(t: Map[Int, B]) extends Map[Int, B]  {
  private val internalMap = t
  def +[B1 >: B](kv: (Int, B1)) = new MyMap(internalMap + kv)
  def -(key: Int) = new MyMap(internalMap - key)
  def get(key: Int) = internalMap.get(key)
  def iterator = internalMap.iterator
}

scala> MyMap()
res1: MyMap[Int,String] = Map(1 -> one, 2 -> two)

关于scala - Scala父类(super class)构造函数中的“Too many arguments”错误,但在REPL中不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13166140/

相关文章:

python - pip安装pyaudio错误cl.exe失败

compilation - 在 CentOS 6.0 上编译单声道时 undefined reference

database - Lift 映射器中的外键约束

scala - Scala 文档中的 "Shadowed Implicit Value Members"是什么?

scala - 在 Spark 中将列标记为分类

抽象类的 C++ 保护构造函数

scala - 如何在 sbt 中执行 grep

c++ - 对象在构造函数之后不存在?

Java:抽象类构造函数和 this()

python - 在virtualenv python3.4中安装django,在virtualenv中安装linux os