2013-08-29 55 views

回答

2

他們說的是協方差和逆變,看到http://debasishg.blogspot.ch/2006/04/generics-in-scala-part-1_12.html

具體報價:

的+中類定義類型參數表明 子類型是該類型參數的協變。 A - 在同一地點 將關係改變爲反轉。默認(沒有任何 前綴)聲明表示不變的子類型。

+1

另一篇文章:http://www.scala-lang.org/old/node/129 – user573215

+1

逆變函數:) –

+0

Woops,是啊,修正:) –

2

沒有進入細節短(不完整)答案:

他們指定類型參數和繼承關係之間的關係。

  • +指示如果TS然後Class[T]一個子類是Class[S]
  • -一個子類表示如果ST然後Class[T]一個子類是Class[S]
  • 一個子類。如果既不是本,那麼在Class tClass s之間將沒有繼承關係

如果您熟悉Java,那麼您知道第三種情況是每個具有類型參數的Java類。 (List<T>List<S>之間沒有關係,即使TS的子類)

+0

您能否解釋與您的協變,逆變和不變相關的問題回答? – nish1013

+1

'+'標記協變,'-'標記是逆變的,並且缺少'-'或'+'標記不變類型參數 –

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] 

所以對於反方差可以的地方得到的預期,反之亦然任何基類對象對於協方差,您可以將任何派生類對象放在需要基數的位置。通常,方法參數是反變量的,它們的返回類型是共變的。

+0

您能添加此程序的輸出以使其更加可用嗎? – nish1013

+0

已添加。看到「會產生」。 – user4298319