+ - 在Scala中签署通用声明

时间:2014-12-23 20:49:14

标签: scala generics

我在查看this link中的PartialFunction文档:

trait PartialFunction[-A, +B] extends (A) ⇒ B

也许有人可以帮助澄清通用声明中加号和减号的重要性?

3 个答案:

答案 0 :(得分:28)

“+”和“ - ”分别表示covariant and contravariant类型。简而言之,它意味着:

PartialFunction[-A1, +B1]&lt ;: PartialFunction[-A2, +B2]仅在A1 :> A2B1 <: B2时,其中<:是子类型关系。

“ - ”通常用于输入参数,“+”用于输出 - 在C#中,它们甚至使用相应的关键字inout。在存在类型上还建立了一些更原始的generic variance support in Java - 实际上你可以在Scala中使用_ <: SomeType(协方差)或抽象类型成员type T <: SomeType来实现它。

没有修饰符PartialFunction[A1, B1]PartialFunction[A2, B2]没有直接关系(换句话说,它将是不变的)。

P.S。对这些类型也有一些限制,例如协变(“+”)类型不能处于逆变位置(您只能从方法返回它),反之亦然。这样做是为了支持Liskov Substitution Principle并通过“in”/“out”解释自然可以理解。

另外,值得注意的是A => BFunction1的语法糖)本身正在使用共同/反对方差:

 trait Function1 [-T1, +R] extends AnyRef

由于这些函数可以通过子类型进行扩展,这使得它们在理论上也是部分的(尽管Scala不是这些函数的处理方式) - 甚至技术上Scala中的“total”FunctionN可以扩展,重新定义,返回null等等。

答案 1 :(得分:16)

它的协方差和逆变。 https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

基本上它说Generic类型继承如何工作。 来自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]

答案 2 :(得分:5)

为了补充其他答案,以下是scala-lang网站上差异文档的链接:

https://docs.scala-lang.org/tour/variances.html