我正在为类似地图的容器实现一个非常简单的构建器模式:
trait KeyValueContainer[K,V] {
private var props: Map[K, V] = new HashMap[K, V]
private var built = false
/**
* Adds a key/value pair
*/
def +=(key: K, value: V): KeyValueContainer[K,V] = {
if (built)
throw new BuilderException
props = props + (key -> value)
this
}
def build = {
built = true
this
}
}
class MyContainer extends KeyValueContainer[String, Double]
在“new MyContainer()”上使用上述“+ =”或“build”方法时,两个场景中的结果类型为KeyValueContainer [String,Double] ......
我很确定我在过去的某个地方读到这可能会以某种方式返回实际的MyContainer子类型。你会为此(Java风格)使用方法返回类型协方差,还是在视图中有更多类型安全/更好的解决方案?
谢谢!
答案 0 :(得分:1)
这就是:
http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html
该模式依赖于在编译时如何解决implicits。基本上,如果范围内有多个含义,编译器会选择最具体的含义(在您的情况下,是您需要的子类型构建器)。
通过这种方式,您可以在基类中执行泛型实现,并通过隐式参数获取子类构建器。
以下是我为自己的一个项目所做的一个例子:
https://gist.github.com/hejfelix/8a0270855d498d7981f9
此模式的另一个重要方面是显式自我输入: http://www.scala-lang.org/node/124
答案 1 :(得分:1)
我推荐这篇文章,它更简单,更重要的是:
通过使用this.type了解如何自行返回,并以此为基础。
trait PaginationParameters extends Parameters {
var _pageSize: Option[Int] = None
var _page: Option[Int] = None
def pageSize(newPageSize: Int): this.type = {
_pageSize = Some(newPageSize); this
}
def page(newPage: Int): this.type = {
_page = Some(newPage); this
}
override def parameters = super.parameters ++
_pageSize.map("page-size" -> _) ++
_page.map("page" -> _)
}
}
干杯