2017-08-02 103 views
-1
  1. 鑑於下面的類定義爲什麼T是在協方差位置或逆變位置

    類X [+ T] { DEF得到[U>:T] (default:U):U }

爲什麼T IN的方法def get[U>:T](默認值:U)是在協方差位置

  • 給出下面的類定義

    類X [-T] { DEF得到[C <:T] (default:U):U }

  • 爲什麼T IN的方法def get[U<:T](默認值:U)是在cotravariance位置

    回答

    1

    很難回答「爲什麼?」沒有你提供更多細節的問題,但我會嘗試。我假設你的問題真的是「爲什麼U的類型限制沒有被反轉?」。簡短的回答:因爲這是類型安全的並且涵蓋了一些其他情況沒有涉及的情況。

    您的第一個示例可能受Option[T]及其getOrElse方法的啓發。雖然我不確定爲什麼有人需要getOrElseUT不同,但爲什麼類型限制只能是U>:T的邏輯對我來說似乎很明顯。假設您有3個類別:C,它繼承B,繼承A,並且您有Option[B]。如果您的default值已經爲BC您不需要除U = T之外的任何內容,因此無需其他通用U即可更簡單的簽名就足夠了。唯一不能將默認值傳遞給getOrElse方法的情況是,如果您有某種類型的子類型不是B(例如A),則該方法是不可用的。讓我們來擴展這個簽名更片刻

    def getOrElse[U, R](default:U): R 
    

    如何類型UTR應該有關係嗎?顯然R應該是一些常見的超類型UT,因爲它應該能夠包含TU。然而,這樣的定義會是一個矯枉過正。首先,具有與T完全不相關的類型的默認值真的很奇怪。其次,即使是這樣一個奇怪的情況,你(和編譯器)仍然可以計算一個普通的超類型並將其分配給一些新的U' = R'。因此,您不需要R,但添加U會增加一些靈活性(至少在理論上)。但U仍然必須是一些超級類型的T,因爲它也是返回類型。

    所以總結起來:加入UU<:T

    • 如果使用U的結果類型(U結果類型不能容納T
    • ,或者如果你要麼產生錯誤的代碼使用T作爲結果類型不會擴展此方法的適用性,即不會允許任何代碼在沒有U的情況下無法編譯時使用此額外的U進行編譯。

    但添加UU>:T將允許更多的代碼這實際上是類型安全的編譯,如(是的,愚蠢的例子,但正如我所說,我不知道任何現實生活中的例子):

    val opt = Option[Int](1) 
    val orElse: Any = opt.getOrElse(List()) 
    
    +0

    謝謝@serggr。 – Tom