Scala编译器如何定位方差注解位置及检查协变逆变位置?
Scala协变类型参数的位置检查逻辑解析
首先咱们得明确Scala里协变注解+T的核心规则:标注了协变的类型参数,只能出现在「输出位置」,绝对不能出现在「输入位置」。
你举的例子刚好踩了这个红线:
class Foo[+T] { def bar(param: T): Unit = println("Hello foo bar") }
这段代码编译肯定通不过,因为bar方法的参数param属于「输入位置」——方法接收一个T类型的参数,这就违反了协变的约束。
为啥编译器要卡这个?本质是为了保证类型安全。咱们举个具体场景理解:
假设String是Any的子类型,那么协变的Foo[String]应该能被当成Foo[Any]来用(这是协变的核心意义:子类型关系可以传递)。但如果Foo[Any]的bar方法能接收任意Any类型的参数,那当我们把Foo[String]当作Foo[Any]调用bar(123)时,Foo[String]的bar其实只能处理String类型,这就会导致类型错误,编译器必须提前拦住这种情况。
再补充个对比规则:
- 协变
+T允许的位置:方法返回值、类的val成员(比如val value: T),这些都是「输出位置」——向外提供T类型的值; - 如果是逆变
-T,则刚好相反:可以用在输入位置(比如方法参数),但不能用在输出位置。
内容的提问来源于stack exchange,提问作者ruach
相关产品推荐
相关产品推荐

