嗨,我想讓我的頭在Scala上。Scala +/- 類型params之前的符號
我指的是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上。Scala +/- 類型params之前的符號
我指的是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 - 在同一地點 將關係改變爲反轉。默認(沒有任何 前綴)聲明表示不變的子類型。
沒有進入細節短(不完整)答案:
他們指定類型參數和繼承關係之間的關係。
+
指示如果T
是S
然後Class[T]
一個子類是Class[S]
-
一個子類表示如果S
是T
然後Class[T]
一個子類是Class[S]
Class t
和Class s
之間將沒有繼承關係如果您熟悉Java,那麼您知道第三種情況是每個具有類型參數的Java類。 (List<T>
和List<S>
之間沒有關係,即使T
是S
的子類)
您能否解釋與您的協變,逆變和不變相關的問題回答? – nish1013
'+'標記協變,'-'標記是逆變的,並且缺少'-'或'+'標記不變類型參數 –
我同意這裏的答案,只是想展示一些例子。隨着[-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]
所以對於反方差可以的地方得到的預期,反之亦然任何基類對象對於協方差,您可以將任何派生類對象放在需要基數的位置。通常,方法參數是反變量的,它們的返回類型是共變的。
您能添加此程序的輸出以使其更加可用嗎? – nish1013
已添加。看到「會產生」。 – user4298319
另一篇文章:http://www.scala-lang.org/old/node/129 – user573215
逆變函數:) –
Woops,是啊,修正:) –