Kotlin類型安全閥門:簡單理解in和out流向控制,拒絕類型翻車!
在開發(fā)中,Kotlin泛型類型的安全性就像水杯的「防燙設(shè)計」——in和out這兩個關(guān)鍵字能幫我們避免類型燙傷。
理解Kotlin中的in和out
場景一:安全的容器(out關(guān)鍵字)想象你有一個只能倒水的飲水機(jī),這就是out的作用。我們定義飲水機(jī)接口:
interface WaterDispenser<out T> {
fun pour(): T // 只能倒水
}
class ColdWater : Water() // 冷水類型
open class Water() // 基礎(chǔ)水類型
// 冷水機(jī)實現(xiàn)
class ColdDispenser : WaterDispenser<ColdWater> {
override fun pour() = ColdWater()
}
fun main() {
// 基礎(chǔ)飲水機(jī)裝冷水(安全操作)
val dispenser: WaterDispenser<Water> = ColdDispenser()
val myWater: Water = dispenser.pour()
// dispenser.reload(ColdWater()) ← 會報錯!這里禁止裝水
}
關(guān)鍵點:
? 當(dāng)使用out時,相當(dāng)于給容器貼上「只出不進(jìn)」的標(biāo)簽
? 允許把冷水機(jī)當(dāng)作普通飲水機(jī)使用(向上兼容)
? 禁止添加任何裝水的方法(編譯器會報錯)
場景二:智能垃圾桶(in關(guān)鍵字)現(xiàn)在有個只能裝垃圾的智能垃圾桶,這就是in的作用。定義垃圾處理接口:
interface TrashBin<in T> {
fun dispose(item: T)// 只能裝垃圾
}
open class Garbage // 基礎(chǔ)垃圾
class FoodWaste : Garbage() // 廚余垃圾
// 廚余垃圾桶實現(xiàn)
class FoodBin : TrashBin<FoodWaste> {
overridefun dispose(item: FoodWaste) {
println("處理廚余垃圾:${item.hashCode()}")
}
}
fun main() {
// 普通垃圾桶裝廚余垃圾(安全操作)
val bin: TrashBin<FoodWaste> = FoodBin()
bin.dispose(FoodWaste())
// val found = bin.retrieve() ← 會報錯!禁止取垃圾
}
關(guān)鍵點:
- ?in相當(dāng)于「只進(jìn)不出」的封印
- ? 允許處理更具體的垃圾類型(向下兼容)
- ? 禁止任何取垃圾的操作(編譯保護(hù))
類型安全的三把鑰匙
生產(chǎn)消費模型:
? 生產(chǎn)者用out(如數(shù)據(jù)讀取器)
interface DataReader<out T> {
fun readNext(): T
}
? 消費者用in(如數(shù)據(jù)處理器)
interface DataProcessor<in T> {
fun process(input: T)
}
集合操作示例
fun copyData(src: List<out String>, dest: MutableList<in String>) {
for (item in src) {
dest.add(item) // 安全操作:src只讀,dest只寫
}
}
錯誤規(guī)避指南
錯誤場景 | 編譯器提示 |
在out類型中嘗試寫入 | Type mismatch 錯誤 |
在in類型中嘗試讀取 | Cannot access 'XXX' 錯誤 |
混用泛型修飾符 | Conflicting variance 錯誤 |
為什么需要方向控制?
? 防止數(shù)據(jù)污染:就像不能把臟水倒回飲水機(jī)
? 提升代碼彈性:冷水機(jī)可以當(dāng)作普通飲水機(jī)使用
? 編譯期類型檢查:在寫代碼時就發(fā)現(xiàn)問題,避免運行時崩潰
總結(jié)就是:
? 向外拿用out(輸出數(shù)據(jù))
? 往里塞用in(輸入數(shù)據(jù))
? 泛型箭頭方向:out相當(dāng)于? extends T,in相當(dāng)于? super T
通過控制數(shù)據(jù)流向,in和out就像給代碼加上智能閥門。記住:當(dāng)需要安全地處理繼承關(guān)系中的類型轉(zhuǎn)換時,這兩個關(guān)鍵字就是你的類型安全衛(wèi)士。下次寫泛型時,先問自己:這個容器是用來取東西還是裝東西的?