Scala + / - 签署类型参数之前的符号

时间:2013-08-29 09:19:32

标签: scala

您好,我正试图了解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之前意味着什么?

3 个答案:

答案 0 :(得分:2)

它们表示协方差和逆变,请参阅http://debasishg.blogspot.ch/2006/04/generics-in-scala-part-1_12.html

具体来说,引用:

  

类定义的+ in type参数表示   子类型对该类型参数是协变的。 A - 在同一个地方   将关系改为逆变。默认(没有任何   prefix)声明表示子类型的不变性。

答案 1 :(得分:2)

一个简短的(而不是完整的)答案,但没有详细说明:

它们指定类型参数和继承关系之间的关系。

  • +表示如果TS的子类,则Class[T]Class[S]的子类
  • -表示如果ST的子类,则Class[T]Class[S]的子类
  • 如果两者都不存在,则Class tClass s
  • 之间不存在继承关系

如果您熟悉Java,那么您知道第三种情况是每个带有类型参数的Java类。 (List<T>List<S>之间没有任何关系,即使TS的子类

答案 2 :(得分:2)

我同意这里的答案,只想展示一些例子。使用[-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]

因此,对于反差异,您可以将任何基类对象放置在期望派生的位置,反之亦然,可以将任何派生类对象放在需要基数的位置。通常,方法参数是反变量的,它们的返回类型是共变量。