<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ## 泛型約束 ### 泛型約束的必要性 **泛型約束是對類或者方法中的類型變量進行約束**。當創建一個泛型List<E>時,類型變量E理論上是可以被替換為任意的引用類型,但是**有時候需要約束泛型實參的類型**,例如想對E類型變量求和,則E應該是Int類型、Long類型、Double類型或者Float類型等,而不應該是String類型,因此在特殊情況下,需要對類型變量E進行限制。接下來我們通過一個案例來學習泛型約束的相關知識,具體代碼如下所示。 ``` fun <T : Number> List<T>.sum(): Double? { var sum: Double? = 0.0 //定義一個Double類型的變量sum for (i in this.indices) { //遍歷傳遞過來的集合中的數據 sum = sum?.plus(this[i].toDouble()) //轉化為Double類型再與sum相加 } return sum } fun main(args: Array<String>) { var list = arrayListOf(1, 2, 3, 4, 5) //創建一個集合變量list println("求和:${list.sum()}") } ``` 運行結果: ``` 求和:15.0 ``` 上述代碼中,**創建了一個泛型方法sum(),該方法的返回值為Double類型,泛型為List<T>,其中對類型變量T的約束為Number類型,也就是調用sum()方法的集合中的類型必須是Number類型**。在main()方法中可以看到,創建了一個list集合,這個集合中的數據設置的都是Int類型,Int類型屬于Number類型,因此在該程序中可以通過list集合來調用sum()方法實現求和功能。**如果傳入的類型不屬于Number類型則會拋出類型不匹配異常**。 ### 泛型約束<T:類或接口> 泛型約束`<T:類或接口>`與Java中的<? extends類或接口>類似,這個約束也可以理解為**泛型的上界**。例如泛型約束<T:BoundingType>,其中BoundingType可以稱為綁定類型,綁定類型可以是類或者接口。如果綁定類型是一個類,則類型參數T必須是BoundingType的子類。如果綁定類型是一個接口,則類型參數T必須是BoundingType接口的實現類。接下來我們來針對如何調用泛型上界類中的方法與泛型約束`<T:Any?>`與`<T:Any>`進行詳細講解。 #### 調用泛型上界類中的方法 **如果泛型約束中指定了類型參數的上界,則可以調用定義在上界類中的方法**。 接下來我們通過一個案例來調用上界類中的方法,具體代碼如下所示。 ``` fun <T : Number> twice(value: T): Double { return value.toDouble() * 2 } fun main(args: Array<String>) { println("4.0的兩倍:${twice(4.0f)}")//將4.0f傳遞到twice()中并打印結果 println("4的兩倍:${twice(4)}") //將4傳遞到twice()中并打印結果 } ``` 運行結果: ``` 4.0的兩倍:8.0 4的兩倍:8.0 ``` 在上述代碼的twice()方法中,參數value調用的toDouble()方法是在Number類中定義的。由于在泛型約束`<T:Number>`中已經指定類型參數的上界為Number,因此twice()方法中傳遞的參數value可以調用定義在上界類Number中的方法。 ##### 多重上界 **如果上界約束需要多個約束,則可以通過where語句來完成**。接下來我們通過where關鍵字來實現上界約束的多個約束,具體示例代碼如下: ``` fun <T> manyConstraints(value: T) where T : CharSequence, T : Appendable { if (!value.endsWith('.')) { value.append('.') } } ``` 從上述代碼中可以看到,**通過where關鍵字實現了上界約束的多個約束,每個約束中間用逗號分隔**,并且傳遞的參數value可以調用第1個約束CharSequence類中的endsWith()方法,同時也可以調用第2個約束Appendable類中的append()方法。 #### 泛型約束<T:Any?>與<T:Any> 在泛型`<T:類或者接口>`中,有兩種特別的形式,分別是`<T:Any?>`和`<T:Any>`,其中`<T:Any?>`表示類型實參是Any的子類,且**類型實參可以為null**。`<T:Any>`表示類型實參是Any的子類,且**類型實參不可以為null**。 在Kotlin中,Any類型是任意類型的父類型,類似Java中的Object類,因此聲明的<T:Any?>等同于<T>。接下來我們通過一個案例來演示如何使用泛型<T:Any?>,具體代碼如下所示。 ``` //聲明<T : Any?>等同于<T> fun <T : Any?> nullAbleProcessor(value: T) { value?.hashCode() } fun <T : Any> nullDisableProcessor(value: T) { value.hashCode() //編譯通過 } fun main(args: Array<String>) { nullAbleProcessor(null) // nullDisableProcessor(null) 編譯錯誤 } ``` 上述代碼中,nullAbleProcessor()方法中的類型參數T使用的是`<T:Any?>`進行約束的,**`<T:Any?>`表示可以接收任意類型的類型參數,這個任意類型中包含null**,因此在main()方法中調用nullAbleProcessor()方法時,這個方法中可以傳遞null。nullDisableProcessor()方法中傳遞的類型參數T使用的是`<T:Any>`進行約束的,**`<T:Any>`表示可以接收任意類型的類型參數,這個任意類型中不包含null**,因此在main()方法中調用nullDisableProcessor()方法,且這個方法中傳遞null時,編譯器會自動提示`“is not satisfied:inferred type Nothing? is not a subtype of Any”`,也就是“類型匹配不成功,傳遞的null不是Any的子類型”。 如果想在上述代碼的nullDisableProcessor()方法中傳遞null,則可以將傳遞的參數類型T改為T?,編譯就可以通過了。修改后的代碼如下所示。 ``` //聲明<T : Any?>等同于<T> fun <T : Any?> nullAbleProcessor(value: T) { value?.hashCode() } fun <T : Any> nullDisableProcessor(value: T?) { value?.hashCode() //編譯通過 } fun main(args: Array<String>) { nullAbleProcessor(null) nullDisableProcessor(null) } ``` 上述代碼中,將nullDisableProcessor()方法中傳遞的參數類型T改為T?,第6行代碼從上面的`“value.hashCode()”`改為了`“value?.hashCode()”`,這樣修改后即使使用`<T:Any>`進行約束傳遞的參數類型,也可以允許該方法中傳遞null值。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看