我有以下的(简化)类,包装了一个Map
:
class Store(val values: Map[String, String]) {
def set(name: String, value: String): Store = new Store(values + (name -> value))
def remove(name: String): Store = new Store(values - name)
}
我想有其他类扩展为覆盖,也就是说, toString
方法:
class PrintableStore(values: Map[String, String]) extends Store(values) {
override def toString: String = values.toString
}
这个问题,在事后很明显,是set
和remove
的回报情况Store
:这些方法的返回值是类型不正确,和我失去我的增强toString
方法。
我能找到的唯一的解决办法是定义Store
与自我类型特点如下:
trait Store[+Self] {
this: Self =>
def values: Map[String, String]
def copy(values: Map[String, String]): Self
def set(name: String, value: String): Self = copy(values + (name -> value))
def remove(name: String): Self = copy(values - name)
}
class PrintableStore(val values: Map[String, String]) extends Store[PrintableStore] {
override def toString: String = values.toString
override def copy(values: Map[String, String]): PrintableStore = new PrintableStore(values)
}
这工作得很好,但需要什么,我觉得是对样板Scala代码数量惊人的:
- 所有子类都将有一个实现
copy
是基本相同的。 - 所有子类都将始终通过自己作为参数类型
Store
。
有没有更好的解决这个问题,还是我宠坏了,我的样板门槛太低? 我必须承认,虽然我觉得我了解自己的类型,我不能完全自如地使用他们又和以前的代码很可能是完全不正确。