Kotlin 泛型中的 in 和 out

2021-09-13 18:22:03 字數 2683 閱讀 2355

簡評:在 kotlin 中使用泛型你會注意到其中引入了 in 和 out,對於不熟悉的開發者來說可能有點難以理解。從形式上講,這是一種定義逆變和協變的方式,這篇文章就來講講怎麼來理解和記住它們。

out (協變)如果你的類是將泛型作為內部方法的返回,那麼可以用 out:

inte***ce production
可以稱其為 production class/inte***ce,因為其主要是產生(produce)指定泛型物件。因此,可以這樣來記:produce = output = out。

in(逆變)

如果你的類是將泛型物件作為函式的引數,那麼可以用 in:

inte***ce consumer
可以稱其為 consumer class/inte***ce,因為其主要是消費指定泛型物件。因此,可以這樣來記:consume = input = in。

invariant(不變)

如果既將泛型作為函式引數,又將泛型作為函式的輸出,那就既不用 in 或 out。

inte***ce productionconsumer
假設我們有乙個漢堡(burger)物件,它是一種快餐,當然更是一種食物。

1. 漢堡提供者根據上面定義的類和介面來設計提供 food, fastfood 和 burger 的類:

class foodstore : production

}class fastfoodstore : production

}class inoutburger : production

}

現在,我們可以這樣賦值:

val production1 : production= foodstore()

val production2 : production= fastfoodstore()

val production3 : production= inoutburger()

很顯然,漢堡商店屬於是快餐商店,當然也屬於食品商店。

因此,對於 out 泛型,我們能夠將使用子類泛型的物件賦值給使用父類泛型的物件。

而如果像下面這樣反過來使用子類 - burger 泛型,就會出現錯誤,因為快餐(fastfood)和食品(food)商店不僅僅提供漢堡(burger)。

val production1 : production= foodstore()  // error

val production2 : production= fastfoodstore() // error

val production3 : production= inoutburger()

2. 漢堡消費者再讓我們根據上面的類和介面來定義漢堡消費者類:

class everybody : consumer

}class modernpeople : consumer

}class american : consumer

}

現在,我們能夠將 everybody, modernpeople 和 american 都指定給漢堡消費者(consumer):

val consumer1 : consumer= everybody()

val consumer2 : consumer= modernpeople()

val consumer3 : consumer= american()

很顯然這裡美國的漢堡的消費者既是現代人,更是人類。

因此,對於 in 泛型,我們可以將使用父類泛型的物件賦值給使用子類泛型的物件。

同樣,如果這裡反過來使用父類 - food 泛型,就會報錯:

val consumer1 : consumer= everybody()

val consumer2 : consumer= modernpeople() // error

val consumer3 : consumer= american() // error

根據以上的內容,我們還可以這樣來理解什麼時候用 in 和 out:

英文原文:in and out type variant of kotlin

原文: 

Kotlin 泛型中的 in 和 out

當我們在 kotlin 中定義泛型時,我們會發現它需要使用到in和out兩個關鍵字來定義。從形式上來講,這是一種定義 逆變 和 協變 的方式。那啥叫逆變?啥叫協變?可以參考下維基百科的定義 協變與逆變 out 協變 如果泛型類只將泛型型別作為函式的返回 輸出 那麼使用 out inte ce pro...

Kotlin 泛型中的 in 和 out

簡評 在 kotlin 中使用泛型你會注意到其中引入了 in 和 out,對於不熟悉的開發者來說可能有點難以理解。從形式上講,這是一種定義 逆變和協變的方式,這篇文章就來講講怎麼來理解和記住它們。in out 怎麼記?out 協變 如果你的類是將泛型作為內部方法的返回,那麼可以用 out inte ...

Kotlin筆記之泛型(一)

泛型類和函式 型別引數約束 泛型允許定義帶型別形參的型別,當這種型別的例項被建立出來的時候,型別形參被替換成稱為型別實參的具體型別 例項 原始碼listof函式宣告 funlistof vararg elements t list val list listof hello world 編譯器推導 ...