我在查看this link中的PartialFunction文档:
trait PartialFunction[-A, +B] extends (A) ⇒ B
也许有人可以帮助澄清通用声明中加号和减号的重要性?
答案 0 :(得分:28)
“+”和“ - ”分别表示covariant and contravariant类型。简而言之,它意味着:
PartialFunction[-A1, +B1]
&lt ;: 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]
没有直接关系(换句话说,它将是不变的)。
P.S。对这些类型也有一些限制,例如协变(“+”)类型不能处于逆变位置(您只能从方法返回它),反之亦然。这样做是为了支持Liskov Substitution Principle并通过“in”/“out”解释自然可以理解。
另外,值得注意的是A => B
(Function1
的语法糖)本身正在使用共同/反对方差:
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网站上差异文档的链接: