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

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

问题描述

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

EDIT: Re-written this question based on original answer

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

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 的类型参数是不变的,因为集合背后的概念是函数.以下签名应该稍微澄清一下:

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
}

如果 SetA 中是协变的,则 apply 方法将无法采用 A 由于函数的逆变性.Set 可能在 A 中是 逆变,但是当您想要执行以下操作时,这也会导致问题:

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]

简而言之,最好的解决方案是保持事物不变,即使对于不可变的数据结构也是如此.您会注意到 immutable.Map 在其类型参数之一中也是不变的.

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 的不可变 Set 在其类型上不是协变的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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