我正在编写一个类,它使用一些自定义构造函数逻辑扩展了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/