为什么Seq [V]不扩展Map [Int,V],Set [V]也不扩展Map [V,Bool]?

时间:2011-01-05 00:26:57

标签: oop scala subclass

Iterable的三个直接子类型为MapSeqSet。似乎除了性能问题之外 - Seq是从整数到值的映射,Set是从值到布尔值的映射(如果值在集合中则为true,否则为false)

如果是这种情况,为什么不通过Seq[V]扩展Map[Int, V]Set[V]扩展Map[V, Boolean]来在类型系统中表达?

3 个答案:

答案 0 :(得分:12)

嗯,他们有点做,至少实际上是常见的功能。 Seq[B]继承自Int => B(来自PartialFunction[Int, B]),Map[A, B]继承自A => B(也来自PartialFunction[A, B]),Set[A]继承来自A => Boolean。因此,就功能应用和组合方法而言,所有三种都可以互换使用。此外,就遍历而言,它们可以互换使用,因为所有实现TraversableLike

答案 1 :(得分:8)

将序列视为从整数到元素的赋值只是描述序列是什么的一种方式。还有其他方法,没有理由说这种描述序列的方式应该成为规范。序列的实际目的是使一堆元素可访问和遍历。不需要序列来实际为元素分配整数。例如,大多数Stream实现可能没有与遍历并行运行的计数器。要求这会给实施带来不必要的开销。

此外,Map[K,V]也是Iterable[(K,V)]。根据您的建议,Seq[A]也必须是Map[Int,A],这也会使其成为Iterable[(Int,A)]。由于Seq扩展Iterable,这会使Seq[A]同时成为Iterable[A]Iterable[(Int,A)](并且,递归地,Iterable[(Int,(Int,A))],{{ 1}},等等,这不是Scala中允许的继承方式。

您可以针对Iterable[(Int,(Int,(Int,A)))]

的建议构建类似的论点

答案 2 :(得分:4)

好吧,如果所有你关心的是SeqSet就是那个,那么你有一个观点。我自己,我碰巧认为这是最不重要的方面之一,而且已经很好地代表了所有这些方面的功能

也就是说,Map是值中的键的函数,Seq是值Int的函数,而Set是值的函数为Boolean。这个属性,你称之为“地图”,是一个功能。它已经被所有三个人共享。

在我看来,MapSeqSet的真正含义是:

  • Seq关注的是知道其元素的顺序。从概念上讲,您如何在Map中添加元素?你必须重新编号所有键!

  • Set关注元素的存在与否。如何在Map中对此进行建模?它必须是具有默认值的地图 - 不是公共地图 - 并且所有非默认值都相同!这显然是一种堕落的行为,而不是一种抽象。

  • Map关注将任意键映射到任意值。 Seq没有任意密钥,Set没有任意值。