为什么Scala的不可变集的类型不协变? [英] Why is Scala's immutable Set not covariant in its type?

查看:55
本文介绍了为什么Scala的不可变集的类型不协变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:根据原始答案重新编写该问题



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

  import scala.collection.immutable._ 

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

def bar():单位= {
val s:Set [String] = Set( Hello ,世界);
foo; //不会编译,无论是否在$ val声明
中明确声明了类型
}


解决方案

Set 的set参数是不变的,这是因为set作为函数的概念。以下签名应稍作澄清:

 特征集[A]扩展(A =>布尔值){
def apply(e:A):布尔值
}

如果 Set A 中是协变的,因此 apply 方法将无法采用参数由于函数的差异性,请键入 A Set A 中可能是 contravariant ,但是当您要做这样的事情:

  def元素:可迭代[A] 
immutable.Map 的类型参数之一也是不变的。


EDIT: Re-written this question based on original answer

The scala.collection.immutable.Set class is not covariant in its type parameter. Why is this?

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 is invariant in its type parameter because of the concept behind sets as functions. The following signatures should clarify things slightly:

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

If Set were covariant in A, the apply method would be unable to take a parameter of type A due to the contravariance of functions. Set could potentially be contravariant in A, but this too causes issues when you want to do things like this:

def elements: Iterable[A]

In short, the best solution is to keep things invariant, even for the immutable data structure. You'll notice that immutable.Map is also invariant in one of its type parameters.

这篇关于为什么Scala的不可变集的类型不协变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆