+- Scala 中的通用声明中的符号
Posted
技术标签:
【中文标题】+- Scala 中的通用声明中的符号【英文标题】:+- Signs in Generic Declaration in Scala 【发布时间】:2014-12-23 20:49:13 【问题描述】:我正在查看 this link 中的 PartialFunction 文档:
trait PartialFunction[-A, +B] extends (A) ⇒ B
也许有人可以帮助澄清泛型声明中加号和减号的意义?
【问题讨论】:
【参考方案1】:“+”和“-”分别表示covariant and contravariant 类型。简而言之,就是:
PartialFunction[-A1, +B1]
<:>PartialFunction[-A2, +B2] 仅当A1 :> A2
和B1 <: B2
,其中<:
是子类型关系。
“-”通常用于输入参数,“+”用于输出 - 在 C# 中,它们甚至使用各自的关键字 in
和 out
。还有一些更原始的generic variance support in Java 建立在存在类型之上——实际上你也可以在Scala 中使用_ <: SomeType
(协方差)或抽象类型成员type T <: SomeType
。
如果没有修饰符 PartialFunction[A1, B1]
将与 PartialFunction[A2, B2]
没有直接关系(换句话说,它将是不变的)。
附:这些类型也有一些限制,例如 covariant("+") 类型不能处于逆变位置(您只能从方法中返回它),反之亦然。这样做是为了支持Liskov Substitution Principle 并且自然可以通过“in”/“out”解释来理解。
另外,值得注意的是A => B
(Function1
的语法糖)本身正在使用 co-/contra-variance:
trait Function1 [-T1, +R] extends AnyRef
因为这些函数可以通过子类型进行扩展,这使得它们在理论上也是局部的(尽管 Scala 不是这样处理这些函数的)——即使从技术上讲,Scala 中的“全部”FunctionN 也可以扩展、重新定义、返回 null 等等。
【讨论】:
【参考方案2】:这是协变和逆变。 https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
基本上它说明了泛型类型的继承将如何工作。
来自 Scala 的简单示例是 - trait Seq[+A]
因为 + ,所以代码
val s: Seq[Person] = Seq[Student]()
将编译,因为 Student 扩展了 Person。没有 + 它将无法工作
更复杂一点的示例 -
class C[-A, +B]
def foo(param: A): B = ???
class Person(val name: String)
class Student(name: String, val university: String) extends Person(name)
val sample: C[Student, Person] = new C[Person, Student]
【讨论】:
【参考方案3】:为了补充其他答案,这里是 scala-lang 网站上差异文档的链接:
https://docs.scala-lang.org/tour/variances.html
【讨论】:
以上是关于+- Scala 中的通用声明中的符号的主要内容,如果未能解决你的问题,请参考以下文章