3

嗨,我正在尝试了解 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 前面的 + 和 - 是什么意思?

4

3 回答 3

2

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

具体来说,引用:

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

于 2013-08-29T09:25:54.770 回答
2

一个简短(不完整)的答案,无需详细说明:

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

  • +表示 ifT是一个子类SthenClass[T]是一个子类Class[S]
  • -表示 ifS是一个子类TthenClass[T]是一个子类Class[S]
  • Class t如果两者都不存在,则和之间将不存在继承关系Class s

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

于 2013-08-29T10:18:46.067 回答
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]

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

于 2013-08-29T14:54:30.263 回答