日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

kotlin学习笔记——泛型及reified函数

發布時間:2024/4/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kotlin学习笔记——泛型及reified函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

kotlin中的泛型與java中的差不多 class TypedClass<T>(param : T){... }val s = TypedClass<String>("hello") kotlin中可以簡化模板代碼,編譯器可以自動推斷類型,如 val s = TypedClass("hello") 但如果接收一個null,編譯器無法推斷類型,仍然需要指定類型,如 val s = TypedClass<String?>(null) 我們可以給泛型添加限制,如: class TypeClass<T : Any>(param : T){... } 這時限制為非null類型,上面接收null的代碼就會報錯了。 我們也可以限制為某種類型的子類,與java中類似,如 class TypedClass<T : Context>(param : T){.... } 這樣所有繼承至Context的類可以使用,其他則不能。 泛型也可以使用在函數中,如 fun <T> do(param : T) List<T>{... }
泛型的變體 在java中,使用泛型時會遇到一些問題,比如使用集合的時候,如 List<String> list1 = Lists.newArrayList(); List<Object> list2 = list1 就會報錯,雖然List<Object>有更弱的限制,因為如果編譯器允許這種行為,后面如果出現下面的代碼就一定會程序崩潰。 list2.add(5); String s = list2.get(0); 但是在java中,我們可以使用addAll,如 List<Object> list2 = Lists.newArrayList(); list2.addAll(list1) 這時因為addAll的函數接收的參數是“Collection<? extends E> items”,這里就用到了泛型的協變。 為了解決類似的問題,為泛型增加了通配符,包括協變和逆變 協變(covariance)——?“? extends XXX” —— 表示限制為XXX及其子類 逆變(contravatiance)—— “? super XXX” —— 表示限制為XXX及其父類 這樣就可以處理上面List的問題,如 List<? extends Object> list2 = list1; 但是通配符都有它的限制,通配符定義的了使用場景變體(use-site variance),當我們使用它的時候都需要聲明它。這表示我們每次聲明一個泛型變量都需要增加模板代碼。例如上面的代碼就增加了一下額外的模板代碼。 在kotlin中,我們可以使用內部聲明變體(declaration-site variance)這種更簡單的方式,來表示當我們定義一個類或接口時可以處理弱限制場景。 相比冗長的通配符,在kotlin中我們可以使用“out”來針對協變,使用“in”來針對逆變。如 class TypedClass<out T>{... }val obj1 = TypedClass<String>() val obj2 : TypedClass<Any> = obj1 這段代碼可以在kotlin中編譯運行(最后一行實際上就相當于val obj2 : TypedClass<? extends Any> = obj1)


下面我們再來說說reified函數,它與泛型密切相關 比如我們啟動一個activity代碼: val intent = Intent(MainActivity@this, javaClass<DetailActivity>) intent.putExtra(DetailActivity.ID, item.id) intent.putExtra(DetailActivity.NAME, item.name) startActivity(intent) anko給我們提供了一個reified function,可以更簡單的實現 startActivity<DetailActivity>(DetailActivity.ID to item.id, DetailActivity.NAME to item.name) 我們知道在java中使用泛型的時候,無法通過泛型來得到Class,一般我們會將Class通過參數傳過去。 在kotlin中一個內聯函數(inline)可以被具體化(reified),這意味著我們可以得到使用泛型類型的Class。 startActivity的源碼如下: public?inline?fun?<reified?T:?Activity>?Context.startActivity(vararg?params:?Pair<String,?String>)?{val?intent?=?Intent(this,?T::class.javaClass)params?forEach?{?intent.putExtra(it.first,?it.second)?}startActivity(intent) } 可以看到使用T::class.javaClass就可以得到使用泛型類型的Class。 startActivity是Context的內聯函數,所以要在Context類中才可以使用,在其他地方使用則需要使用with函數: with(context){startActivity<...>(...) }


?

總結

以上是生活随笔為你收集整理的kotlin学习笔记——泛型及reified函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。