扩展 Scala 集合
我想要一个在尝试覆盖现有键的值时抛出的映射。我尝试过:
trait Unoverwriteable[A, B] extends scala.collection.Map[A, B] {
case class KeyAlreadyExistsException(e: String) extends Exception(e)
abstract override def + [B1 >: B] (kv: (A, B1)): Unoverwriteable[A, B1] = {
if (this contains(kv _1)) throw new KeyAlreadyExistsException(
"key already exists in WritableOnce map: %s".format((kv _1) toString)
)
super.+(kv)
}
abstract override def get(key: A): Option[B] = super.get(key)
abstract override def iterator: Iterator[(A, B)] = super.iterator
abstract override def -(key: A): Unoverwriteable[A, B] = super.-(key)
}
并得到:
<console>:11: error: type mismatch;
found : scala.collection.Map[A,B1]
required: Unoverwirteable[A,B1]
super.+(kv)
^
<console>:16: error: type mismatch;
found : scala.collection.Map[A,B]
required: Unoverwirteable[A,B]
abstract override def -(key: A): Unoverwirteable[A, B] = super.-(key)
^
我对 Scala 很陌生,无法找到克服这个问题的方法。有什么帮助吗? :)
编辑:我正在使用 Scala 2.8.0.Beta1-prerelease (这给 scala.collection 带来了一些变化)
I want a Map that throws on attempt to overwrite a value for existing key. I tried:
trait Unoverwriteable[A, B] extends scala.collection.Map[A, B] {
case class KeyAlreadyExistsException(e: String) extends Exception(e)
abstract override def + [B1 >: B] (kv: (A, B1)): Unoverwriteable[A, B1] = {
if (this contains(kv _1)) throw new KeyAlreadyExistsException(
"key already exists in WritableOnce map: %s".format((kv _1) toString)
)
super.+(kv)
}
abstract override def get(key: A): Option[B] = super.get(key)
abstract override def iterator: Iterator[(A, B)] = super.iterator
abstract override def -(key: A): Unoverwriteable[A, B] = super.-(key)
}
and got:
<console>:11: error: type mismatch;
found : scala.collection.Map[A,B1]
required: Unoverwirteable[A,B1]
super.+(kv)
^
<console>:16: error: type mismatch;
found : scala.collection.Map[A,B]
required: Unoverwirteable[A,B]
abstract override def -(key: A): Unoverwirteable[A, B] = super.-(key)
^
I'm quite new to Scala and can't figure out a way to overcome this. Any help? :)
edit: I'm using Scala 2.8.0.Beta1-prerelease (which brings some changes to scala.collection)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这修复了您的编译错误:
但是,我认为您确实想装饰
collection.mutable.Map#+=
,如下所示:This fixed your compile error:
However, I think you really want to decorate the
collection.mutable.Map#+=
, as follows:当您重写
Map
中的方法时,您无法将您的特征定义为返回类型。最简单的解决方案是省略类型:
或者您可以显式地添加超级类型:
我认为您只需要覆盖
+
,因为您的其他方法仅委托给Map
。As you are overriding methods in
Map
, you can't define your trait as the return type.The easiest solution is to just omit the types:
Or you could be explicit and add the super type:
I think you would only have to override
+
though, as your other methods only delegate toMap
.您可以使用带有一点隐式魔法的 scala.collection.immutable.Map 来完成此操作。也就是说,您在接口中定义一个附加方法和一个隐式转换。这是我在 2.7 中的做法,我确信在 2.8 中可以重写不同的方法,但您应该了解总体思路。
然后,您在伴随对象中定义隐式:
要使用它,请向您的映射添加 Unwriteable 类型注释。如果取消注释 main 方法中的最后 2 行,您将根据需要得到 KeyAlreadyExistsException。
You can do it using a scala.collection.immutable.Map with a little implicit magic. That is, you define one additional method in the interface and an implicit conversion. Here's how I would do it in 2.7, I'm sure there's different methods to override in 2.8, but you should get the general idea.
Then you define the implicit in the companion object:
To use it add an Unwriteable type annotation to your map. If you uncomment the last 2 lines in the main method, you get a KeyAlreadyExistsException as desired.