標籤:

Kotlin語言的類型定義裡面in,out,raw具體都是什麼概念?


子類型關係

Liskov代換原則:派生類(子類)對象能夠替換其基類(超類)對象被使用。

子類型序關係:對於類型的派生的預序關係

其中存在兩個特別的類型,Nothing,Any:(Nothing有沒有一點像空集?)

Nothing≦任意其他類型

任意其他類型≦Any

逆變協變與不變

逆變:類型構造器的某個參數逆轉了子類型序關係

協變:類型構造器的某個參數保持了子類型序關係

比如:

我們有兩個類型廢紙垃圾可回收垃圾

它們有子類型序關係:廢紙 &<: 可回收垃圾

一個對T參數逆變的類型構造器——垃圾桶[T]

(在Kotlin中應該是垃圾桶&,不過尖括弧和看起來不和諧,所以我就使用方括弧表示了)

一個對T參數協變的類型構造器——生產垃圾的小朋友[T]

則:

生產垃圾的小朋友[廢紙] &<: 生產垃圾的小朋友[可回收垃圾]

垃圾桶[可回收垃圾] &<: 垃圾桶[廢紙]

意思是:

一個可以生產廢紙垃圾的小朋友是一個可以生產可回收垃圾的小朋友

一個可以回收可回收垃圾的垃圾桶,可以作為一個可以回收廢紙的垃圾桶用,是一個可以回收廢紙的垃圾桶

在Kotlin中的out 是協變,in是逆變

還有一種情況,不是逆變也不是協變,就是不變(話說,假如類型是偏序關係,能不能得出「不變不僅逆變,而且協變」 ?求大佬解釋……)

Java的Raw Type與Kotlin的Star-Projections

Java的raw type是原生類型,是剝離了類型參數的類型,意思是可以傳入任何類型,失去了類型安全,請避免使用

Kotlin提供了一個星預測來代替,編譯器會把所有的*在協變的參數用out Any?,所有的逆變的參數用in Nothing,保證了類型安全。

==============分割線==============================

2017/10/29 補充

函數的類型規則

如果 A2 &<: A1 且 B1 &<: B2

則 A1 =&> B1 &<: A2 =&> B2

當然,你也還可以按照上面的規則得出

如果 A2 &<: A1 且 B2 &<: B1且 C1 &<: C2

則 A1 =&> B1=&> C1 &<: A2 =&> B2=&> C2

  • 協變類型參數(out)只出現在返回值
  • 逆變類型參數(in)只出現在參數
  • 不變類型參數可以出現在任何地方

我們把函數Unit=&>T成為T的一個getter,把T=&>Unit稱為T的一個setter

則得到,對於任意類型T,T的getter是協變的,T的setter是逆變的。


推薦閱讀:

Kotlin雜談(四) - Coroutines(二): Channel
Android 坑檔案:背黑鍋的 Fragment
#Kotlin# 一年の使用報告 - 類型設計
如何評價 Kotlin 1.0 正式版的的發布?
Android 開發者自述:為什麼我要改用 Kotlin?

TAG:Kotlin |