Scala 为什么可以将集合指定给变量而不能指定参数

Scala 为什么可以将集合指定给变量而不能指定参数,scala,Scala,不像列表是不变的协变函数,集合是不变的函数,我有一个有趣的代码,我不明白它背后的原因是什么 class Fruit case class Apple() extends Fruit val foo: Set[Fruit] = Set(Apple()) // Compile success but why ? Set is an invariant def doStuff(x: Set[Fruit]) = {} val appleSet: Set[Apple] = Set(Apple())

不像列表是不变的协变函数,集合是不变的函数,我有一个有趣的代码,我不明白它背后的原因是什么

class Fruit
case class Apple() extends Fruit

val foo: Set[Fruit] = Set(Apple())  // Compile success but why ? Set is an invariant

def doStuff(x: Set[Fruit]) = {}
val appleSet: Set[Apple] = Set(Apple())
doStuff(appleSet) // Compile failed but why ? assign to a value is fine
该故障原因(Set[Apple])是否未触发类型推断


非常感谢。

下面这一行确实很好:

val foo: Set[Fruit] = Set(Apple())
原因是推断。表达式
Set(Apple())
出现在需要
Set[Fruit]
的上下文中,因此当编译器 查看未将任何类型参数正确地指定给
集。应用
,它将推断此类型参数为
结果
。因此,最终你似乎有:

val foo: Set[Fruit] = Set[Fruit](Apple())
这是完全正确的

现在,如果执行此操作,它将无法编译,正如预期的那样:

scala>val foo: Set[Fruit] = Set[Apple](Apple())
<console>:8: error: type mismatch;
found   : scala.collection.immutable.Set[Apple]
required: Set[Fruit]
scala>val-foo:Set[Fruit]=Set[Apple](Apple())
:8:错误:类型不匹配;
找到:scala.collection.immutable.Set[Apple]
所需:套[果]
甚至这个:

scala> val foo = Set(Apple())
foo: scala.collection.immutable.Set[Apple] = Set(Apple())

scala> val bar: Set[Fruit] = foo
<console>:9: error: type mismatch;
 found   : scala.collection.immutable.Set[Apple]
 required: Set[Fruit]
       val bar: Set[Fruit] = foo
                             ^
scala>val foo=Set(Apple())
foo:scala.collection.immutable.Set[Apple]=Set(Apple())
scala>val-bar:Set[水果]=foo
:9:错误:类型不匹配;
找到:scala.collection.immutable.Set[Apple]
所需:套[果]
val bar:设置[水果]=foo
^
在后一种情况下,
foo
被推断为
Set[Apple]
,而不是
Set[four]
, 因为我们没有为
foo
指定任何显式类型,所以没有用于推断的上下文,并且推断出最具体的类型(最小上界)

至于您的示例中对
doStuff
的调用,它实际上编译得很好。你可能在什么地方又犯了一个错误