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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

kotlin学习之泛型(十四)

發布時間:2024/2/28 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kotlin学习之泛型(十四) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 1. 泛型
  • 2. 通配符(上下界)
  • 3. 泛型函數
  • 4. 泛型約束

本小結介紹的是kotlin的泛型,先從Java的泛型開始介紹:

kotlin中使用泛型的方式跟Java相差不大:

class Box<T>(t: T) {var value = t }// 使用 val box: Box<Int> = Box<Int>(1) //kotlin可以自動推斷類型 val box2 = Box(1)

Java

Java中,在沒有通配符上下界的情況下,是不可變的,也就是說,在指定泛型類型后,Java就能在編譯期確定泛型的類型,防止運行時出現異常。為了泛型的靈活性,提出了通配符上下界。

  • 通配符上界,只能從中讀取元素,不能添加元素,稱為生產者(Producers),用<? extends T>表示。
  • List<String> strs = new ArrayList<String>(); strs.add("0"); strs.add("1"); List<? extends Object> objs = strs; objs.get(0); // 可以獲取 objs.add(1); // 錯誤,不能添加

    之所以不能添加元素的原因很明顯,因為沒法確定添加的實例類型跟定義的類型是否匹配。

  • 通配符下界,只能添加元素,不能直接讀取下界類型的元素,稱為消費者(Consumers),用<? super T>表示。
  • List<String> strs = new ArrayList<String>(); strs.add("0"); strs.add("1"); List<? super String> objs = strs; objs.add("1"); objs.set(0, "2"); //String s = objs.get(0); get不能直接得到String類型的對象 Object s = objs.get(0);

    不得不說,這樣做法是合理的,但是是可能會出錯的。來看看Kotlin是怎么實現類似的情況的。

    kotlin

    在Kotlin中,使用聲明位置變異來解決這種問題:

  • 使用out關鍵字標識的泛型T,只能作為返回值,而不能作為傳入參數。
  • abstract class Source<out T> {// 使用out的話,T只能作為返回值abstract fun nextT(): T// 不能作為傳入參數,下面會報錯// abstract fun add(value: T) }fun demo(strs: Source<String>) {val objects: Source<Any> = strs }

    這種做法實際上就是對應Java中的<? extends T>,因為只能作為返回值而不能作為參數,所以不會出現Java可能出現的運行異常。

  • 使用in關鍵字標識的泛型T,只能作傳入參數,而不能作為返回值。
  • abstract class Source<in T> {// 使用in的話,只能作為傳入參數,不能作為返回值// abstract fun nextT(): Tabstract fun add(value: T) }fun demo(strs: Source<Number>) {val objects: Source<Double> = strs // Double是Number的子類型 }

    這樣是不是更加合理了呢? 用一句概括Kotlin的這種做法,就是:

    Consumer in, Producer out!

    Kotlin同樣支持泛型函數:

    fun <T> singletonList(item: T): List<T> { }fun <T> T.basicToString() : String { // extension function }

    使用的時候,在函數名稱后面指定具體的類型參數:
    val l = singletonList<Int>(1)

    Kotlin的泛型約束和類的繼承一樣,使用:代替extends對泛型的的類型上界進行約束:

    class SwipeRefreshableView<T : View>{}

    同時Kotlin支持多個類型的上界約束,,使用where關鍵字:

    class SwipeRefreshableView<T>where T : View,T : Refreshable { }

    總結

    以上是生活随笔為你收集整理的kotlin学习之泛型(十四)的全部內容,希望文章能夠幫你解決所遇到的問題。

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