编辑: :根据原来的答案重写这个问题

scala.collection.immutable.Set 类的类型参数不是协变的。为什么是这样?

import scala.collection.immutable._

def foo(s: Set[CharSequence]): Unit = {
    println(s)
}

def bar(): Unit = {
   val s: Set[String] = Set("Hello", "World");
   foo(s); //DOES NOT COMPILE, regardless of whether type is declared 
           //explicitly in the val s declaration
}
有帮助吗?

解决方案

Set是因为后面集作为函数的概念在其类型参数是不变的。下列签名应当澄清的事情略有:

trait Set[A] extends (A=>Boolean) {
  def apply(e: A): Boolean
}

如果Set是在A协变,所述apply方法将不能取类型A的参数由于功能的逆变。 Set可能是的逆变的在A,但是当你想要做这样的事情这也导致问题:

def elements: Iterable[A]

总之,最佳解决方案是保持不变的事情,即使是不可变的数据结构。你会发现,immutable.Map也不变其类型参数之一。

其他提示

http://www.scala-lang.org/node/9764 马丁·奥德斯基写道:

  

“关于套的问题,我相信非方差从实现还茎。公共集实现为哈希表,这是关键类型的非变体数组。我同意这是一个有点恼人的不规则性。”

所以,似乎我们所有的努力,构建一个原则性的原因被误导的: - )

编辑: :对于任何想知道为什么这个答案似乎有点偏离主题的人来说,这是因为我(提问者)修改了问题。

Scala 的类型推断足以确定在某些情况下您需要 CharSequences 而不是 Strings。特别是,以下内容在 2.7.3 中对我有用:

import scala.collections.immutable._
def findCharSequences(): Set[CharSequence] = Set("Hello", "World")

至于如何直接创建immutable.HashSets:不。作为实现优化,少于 5 个元素的 immutable.HashSet 实际上并不是 immutable.HashSet 的实例。它们是 EmptySet、Set1、Set2、Set3 或 Set4。这些类是 immutable.Set 的子类,但不是 immutable.HashSet 的子类。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top