kotlin中泛型中in和out的區(qū)別解析
1.概念含義
- in關(guān)鍵字(逆變)
- 在Kotlin泛型中,
in
關(guān)鍵字主要用于定義逆變(Contravariance)。它表示一個(gè)泛型類型參數(shù)可以是指定類型或者它的超類型。 - 簡(jiǎn)單來(lái)說(shuō),就是對(duì)于類型
A
和B
,如果A
是B
的子類型,那么Consumer<B>
是Consumer<A>
的子類型。這里的Consumer
是一個(gè)具有in
關(guān)鍵字修飾泛型參數(shù)的類型,例如接口或者類。
- 在Kotlin泛型中,
- out關(guān)鍵字(協(xié)變)
out
關(guān)鍵字用于定義協(xié)變(Covariance)。它意味著一個(gè)泛型類型參數(shù)可以是指定類型或者它的子類型。也就是說(shuō),對(duì)于類型A
和B
,如果A
是B
的子類型,那么Producer<A>
是Producer<B>
的子類型。這里的Producer
是一個(gè)帶有out
關(guān)鍵字修飾泛型參數(shù)的類型,像接口或者類。
2.使用場(chǎng)景和位置限制
- in關(guān)鍵字
- 主要用于函數(shù)參數(shù)類型:
in
關(guān)鍵字在泛型類型參數(shù)用于函數(shù)參數(shù)時(shí)體現(xiàn)逆變特性。例如,考慮一個(gè)函數(shù)接口AnimalHandler<in T>
,其中T
是用in
修飾的泛型參數(shù)。
- 主要用于函數(shù)參數(shù)類型:
interface AnimalHandler<in T> { fun handle(animal: T): Unit }
- 假設(shè)
Dog
是Animal
的子類型。那么一個(gè)AnimalHandler<Animal>
類型的變量可以接收一個(gè)AnimalHandler<Dog>
類型的值,因?yàn)?code>AnimalHandler在in
位置(函數(shù)參數(shù)位置)是逆變的。
val animalHandler: AnimalHandler<Animal> = object : AnimalHandler<Dog> { override fun handle(dog: Dog): Unit { println("Handling a dog") } }
- 不能用于返回值類型:如果在應(yīng)該返回
T
(in
修飾的泛型參數(shù))的地方使用,會(huì)導(dǎo)致編譯錯(cuò)誤。因?yàn)?code>in規(guī)定這個(gè)類型參數(shù)主要用于接收超類型的值,而不是返回子類型的值。 - out關(guān)鍵字
- 主要用于函數(shù)返回值類型:
out
關(guān)鍵字在泛型類型參數(shù)用于函數(shù)返回值時(shí)體現(xiàn)協(xié)變特性。例如,有一個(gè)接口Producer<out T>
,它用于產(chǎn)生某種類型T
的對(duì)象。
- 主要用于函數(shù)返回值類型:
interface Producer<out T> { fun produce(): T }
- 假設(shè)
String
是Any
的子類型。一個(gè)Producer<String>
可以被當(dāng)作Producer<Any>
來(lái)使用,因?yàn)?code>Producer在out
位置(函數(shù)返回值位置)是協(xié)變的。
val producer: Producer<Any> = object : Producer<String> { override fun produce(): String { return "Hello" } }
不能用于函數(shù)參數(shù)類型:如果試圖將out
修飾的泛型參數(shù)用于函數(shù)參數(shù),編譯器會(huì)報(bào)錯(cuò)。因?yàn)?code>out規(guī)定這個(gè)類型參數(shù)主要用于返回子類型的值,而不是接收子類型的值作為參數(shù)。
3.目的和效果
- in關(guān)鍵字的目的和效果
- 目的是實(shí)現(xiàn)更靈活的函數(shù)參數(shù)類型匹配,特別是在處理超類型和子類型關(guān)系時(shí)。它允許在一個(gè)更通用的類型(超類型)的消費(fèi)者(如接口方法接收超類型參數(shù))中使用更具體的類型(子類型)的實(shí)現(xiàn)。這樣可以使代碼在處理函數(shù)參數(shù)時(shí),能夠以一種逆變的方式利用類型層次結(jié)構(gòu),增強(qiáng)代碼的通用性和靈活性。
- out關(guān)鍵字的目的和效果
- 主要目的是在處理返回值類型時(shí),能夠利用協(xié)變特性,使得代碼更加靈活。通過(guò)允許子類型的生產(chǎn)者(如接口方法返回子類型的值)可以被當(dāng)作更通用類型(超類型)的生產(chǎn)者來(lái)使用,方便在不同層次的類型之間進(jìn)行轉(zhuǎn)換和賦值,同時(shí)保證類型安全。這在構(gòu)建具有多態(tài)性的返回值類型的接口和類時(shí)非常有用,可以讓調(diào)用者以更靈活的方式處理返回值。
到此這篇關(guān)于kotlin中泛型中in和out的區(qū)別的文章就介紹到這了,更多相關(guān)kotlin in和out區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Kotlin-Coroutines中的async與await異步協(xié)程管理
- Kotlin?LinearLayout與RelativeLayout布局使用詳解
- Kotlin FrameLayout與ViewPager2控件實(shí)現(xiàn)滾動(dòng)廣告欄方法
- kotlin協(xié)程之coroutineScope函數(shù)使用詳解
- Kotlin協(xié)程啟動(dòng)createCoroutine及創(chuàng)建startCoroutine原理
- Android結(jié)合kotlin使用coroutine的方法實(shí)例
- Kotlin學(xué)習(xí)教程之協(xié)程Coroutine
相關(guān)文章
Android RecyclerView實(shí)現(xiàn)點(diǎn)擊條目刪除
這篇文章主要為大家詳細(xì)介紹了Android RecyclerView實(shí)現(xiàn)點(diǎn)擊條目刪除,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11設(shè)置Android系統(tǒng)永不鎖屏永不休眠的方法
在進(jìn)行Android系統(tǒng)開發(fā)的時(shí)候,有些特定的情況需要設(shè)置系統(tǒng)永不鎖屏,永不休眠。本篇文章給大家介紹Android 永不鎖屏,開機(jī)不鎖屏,刪除設(shè)置中休眠時(shí)間選項(xiàng),需要的朋友一起學(xué)習(xí)吧2016-03-03Android自定義控件實(shí)現(xiàn)時(shí)間軸
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)時(shí)間軸,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼
這篇文章主要介紹了Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07