嗨,我正在尝试了解 Scala。
我指的是API,发现语法不熟悉
http://www.scala-lang.org/api/current/#scala.actors.CanReply
trait CanReply[-T, +R] extends AnyRef
abstract type Future[+P] <: () ⇒ P
T 和 R 前面的 + 和 - 是什么意思?
嗨,我正在尝试了解 Scala。
我指的是API,发现语法不熟悉
http://www.scala-lang.org/api/current/#scala.actors.CanReply
trait CanReply[-T, +R] extends AnyRef
abstract type Future[+P] <: () ⇒ P
T 和 R 前面的 + 和 - 是什么意思?
它们表示协变和逆变,参见http://debasishg.blogspot.ch/2006/04/generics-in-scala-part-1_12.html
具体来说,引用:
类定义的类型参数中的 + 表示子类型在该类型参数上是协变的。A - 在同一个地方将关系更改为逆变。默认(没有任何前缀)声明表示子类型的不变性。
一个简短(不完整)的答案,无需详细说明:
它们指定类型参数和继承关系之间的关系。
+表示 ifT是一个子类SthenClass[T]是一个子类Class[S]-表示 ifS是一个子类TthenClass[T]是一个子类Class[S]Class t如果两者都不存在,则和之间将不存在继承关系Class s如果您熟悉 Java,那么您就会知道第三种情况是每个带有类型参数的 Java 类。List<T>(和之间没有关系List<S>,即使T是 的子类S)
我同意这里的答案,只是想展示一些例子。通过[-T, +R]协方差和反方差,您可以执行以下操作:
class A
class B extends A
class C extends B
trait CanReply[-T, +R] {
def foo(r: T): R
}
class CR1 extends CanReply[B, B] {
def foo(r: B): B = {
println("arg of type [" + r.getClass() + "] for B in CR1")
new B
}
}
class CR2 extends CanReply[A, C] {
def foo(r: A): C = {
println("arg of type [" + r.getClass() + "] for A in CR2")
new C
}
}
class CR3 extends CanReply[C, A] {
def foo(r: C): A = {
println("arg of type [" + r.getClass() + "] for C in CR3")
new A
}
}
object Program {
def main(args: Array[String]): Unit = {
test(new CR1)
test(new CR2)
test(new CR3)
}
def test(cr: CanReply[C, A]): Unit = {
val res: A = cr.foo(new C)
println("result of type [" + res.getClass() + "]")
println()
}
}
将产生:
arg of type [class C] for B in CR1
result of type [class B]
arg of type [class C] for A in CR2
result of type [class C]
arg of type [class C] for C in CR3
result of type [class A]
因此,对于反方差,您可以将任何基类对象放置在期望派生的位置,反之亦然,对于协方差,您可以将任何派生类对象放置在期望基类的位置。通常方法参数是反变的,它们的返回类型是协变的。