最佳答案
Scala 中最强大的模式之一是 rich-my-library * 模式,它使用到 出现的隐式转换向现有类添加方法,而不需要动态方法解析。例如,如果我们希望所有字符串都具有 spaces
方法来计算它们有多少空格字符,我们可以:
class SpaceCounter(s: String) {
def spaces = s.count(_.isWhitespace)
}
implicit def string_counts_spaces(s: String) = new SpaceCounter(s)
scala> "How many spaces do I have?".spaces
res1: Int = 5
不幸的是,这种模式在处理泛型集合时遇到了麻烦。例如,关于 用集合顺序分组项目已经提出了许多问题。没有任何内置的东西可以一次性完成,所以这似乎是使用通用集合 C
和通用元素类型 A
的 rich-my-library 模式的理想候选者:
class SequentiallyGroupingCollection[A, C[A] <: Seq[A]](ca: C[A]) {
def groupIdentical: C[C[A]] = {
if (ca.isEmpty) C.empty[C[A]]
else {
val first = ca.head
val (same,rest) = ca.span(_ == first)
same +: (new SequentiallyGroupingCollection(rest)).groupIdentical
}
}
}
当然,除了 没用。 REPL 告诉我们:
<console>:12: error: not found: value C
if (ca.isEmpty) C.empty[C[A]]
^
<console>:16: error: type mismatch;
found : Seq[Seq[A]]
required: C[C[A]]
same +: (new SequentiallyGroupingCollection(rest)).groupIdentical
^
这里有两个问题: 我们如何从一个空的 C[A]
列表中获得一个 C[C[A]]
(或者从空气中获得) ?我们如何从 same +:
线取回 C[C[A]]
而不是 Seq[Seq[A]]
线?
* 以前叫皮条客图书馆。