<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 內聯類 [TOC] > 內聯類僅在 Kotlin 1.3 之后版本可用,目前還是*實驗性的*。關于詳情請參見[下文](http://www.kotlincn.net/docs/reference/inline-classes.html#%E5%86%85%E8%81%94%E7%B1%BB%E7%9A%84%E5%AE%9E%E9%AA%8C%E6%80%A7%E7%8A%B6%E6%80%81) 有時候,業務邏輯需要圍繞某種類型創建包裝器。然而,由于額外的堆內存分配問題,它會引入運行時的性能開銷。此外,如果被包裝的類型是原生類型,性能的損失是很糟糕的,因為原生類型通常在運行時就進行了大量優化,然而他們的包裝器卻沒有得到任何特殊的處理。 為了解決這類問題,Kotlin 引入了一種被稱為 `內聯類` 的特殊類,它通過在類的前面定義一個 `inline` 修飾符來聲明: ```kotlin inline class Password(val value: String) ``` 內聯類必須含有唯一的一個屬性在主構造函數中初始化。在運行時,將使用這個唯一屬性來表示內聯類的實例(關于運行時的內部表達請參閱[下文](#表示方式)): ```kotlin // 不存在 'Password' 類的真實實例對象 // 在運行時,'securePassword' 僅僅包含 'String' val securePassword = Password("Don't try this in production") ``` 這就是內聯類的主要特性,它靈感來源于 “inline” 這個名稱:類的數據被 “內聯”到該類使用的地方(類似于[內聯函數](http://www.kotlincn.net/docs/reference/inline-functions.html)中的代碼被內聯到該函數調用的地方)。 ## 成員 內聯類支持普通類中的一些功能。特別是,內聯類可以聲明屬性與函數: ```kotlin inline class Name(val s: String) { val length: Int get() = s.length fun greet() { println("Hello, $s") } } fun main() { val name = Name("Kotlin") name.greet() // `greet` 方法會作為一個靜態方法被調用 println(name.length) // 屬性的 get 方法會作為一個靜態方法被調用 } ``` 然而,內聯類的成員也有一些限制: * 內聯類不能含有 *init*代碼塊 * 內聯類不能含有[幕后字段](http://www.kotlincn.net/docs/reference/properties.html#%E5%B9%95%E5%90%8E%E5%AD%97%E6%AE%B5) * 因此,內聯類只能含有簡單的計算屬性(不能含有延遲初始化/委托屬性) ## 繼承 內聯類允許去繼承接口 ```kotlin interface Printable { fun prettyPrint(): String } inline class Name(val s: String) : Printable { override fun prettyPrint(): String = "Let's $s!" } fun main() { val name = Name("Kotlin") println(name.prettyPrint()) // 仍然會作為一個靜態方法被調用 } ``` 禁止內聯類參與到類的繼承關系結構中。這就意味著內聯類不能繼承其他的類而且必須是 *final*{: .keyword }。 ## 表示方式 在生成的代碼中,Kotlin 編譯器為每個內聯類保留一個包裝器。內聯類的實例可以在運行時表示為包裝器或者基礎類型。這就類似于 `Int` 可以[表示](http://www.kotlincn.net/docs/reference/basic-types.html#%E8%A1%A8%E7%A4%BA%E6%96%B9%E5%BC%8F)為原生類型 `int` 或者包裝器 `Integer`。 為了生成性能最優的代碼,Kotlin 編譯更傾向于使用基礎類型而不是包裝器。 然而,有時候使用包裝器是必要的。一般來說,只要將內聯類用作另一種類型,它們就會被裝箱。 ```kotlin interface I inline class Foo(val i: Int) : I fun asInline(f: Foo) {} fun <T> asGeneric(x: T) {} fun asInterface(i: I) {} fun asNullable(i: Foo?) {} fun <T> id(x: T): T = x fun main() { val f = Foo(42) asInline(f) // 拆箱操作: 用作 Foo 本身 asGeneric(f) // 裝箱操作: 用作泛型類型 T asInterface(f) // 裝箱操作: 用作類型 I asNullable(f) // 裝箱操作: 用作不同于 Foo 的可空類型 Foo? // 在下面這里例子中,'f' 首先會被裝箱(當它作為參數傳遞給 'id' 函數時)然后又被拆箱(當它從'id'函數中被返回時) // 最后, 'c' 中就包含了被拆箱后的內部表達(也就是 '42'), 和 'f' 一樣 val c = id(f) } ``` 因為內聯類既可以表示為基礎類型有可以表示為包裝器,[引用相等](equality.html#引用相等)對于內聯類而言毫無意義,因此這也是被禁止的。 ### 名字修飾 由于內聯類被編譯為其基礎類型,因此可能會導致各種模糊的錯誤,例如意想不到的平臺簽名沖突: ```kotlin inline class UInt(val x: Int) // 在 JVM 平臺上被表示為'public final void compute(int x)' fun compute(x: Int) { } // 同理,在 JVM 平臺上也被表示為'public final void compute(int x)'! fun compute(x: UInt) { } ``` 為了緩解這種問題,一般會通過在函數名后面拼接一些穩定的哈希碼來重命名函數。 因此,`fun compute(x: UInt)` 將會被表示為 `public final void compute-<hashcode>(int x)`,以此來解決沖突的問題。 > 請注意在 Java 中 `-` 是一個 *無效的* 符號,也就是說在 Java 中不能調用使用內聯類作為形參的函數。 ## 內聯類與類型別名 初看起來,內聯類似乎與[類型別名](http://www.kotlincn.net/docs/reference/type-aliases.html)非常相似。實際上,兩者似乎都引入了一種新的類型,并且都在運行時表示為基礎類型。 然而,關鍵的區別在于類型別名與其基礎類型(以及具有相同基礎類型的其他類型別名)是 *賦值兼容* 的,而內聯類卻不是這樣。 換句話說,內聯類引入了一個真實的新類型,與類型別名正好相反,類型別名僅僅是為現有的類型取了個新的替代名稱(別名): ```kotlin typealias NameTypeAlias = String inline class NameInlineClass(val s: String) fun acceptString(s: String) {} fun acceptNameTypeAlias(n: NameTypeAlias) {} fun acceptNameInlineClass(p: NameInlineClass) {} fun main() { val nameAlias: NameTypeAlias = "" val nameInlineClass: NameInlineClass = NameInlineClass("") val string: String = "" acceptString(nameAlias) // 正確: 傳遞別名類型的實參替代函數中基礎類型的形參 acceptString(nameInlineClass) // 錯誤: 不能傳遞內聯類的實參替代函數中基礎類型的形參 // And vice versa: acceptNameTypeAlias(string) // 正確: 傳遞基礎類型的實參替代函數中別名類型的形參 acceptNameInlineClass(string) // 錯誤: 不能傳遞基礎類型的實參替代函數中內聯類類型的形參 } ``` ## 內聯類的實驗性狀態 內聯類的設計目前是實驗性的,這就是說此特性是正在 *快速變化*的,并且不保證其兼容性。在 Kotlin 1.3+ 中使用內聯類時,將會得到一個警告,來表明此特性還是實驗性的。 如需移除警告,必須通過指定編譯器參數 `-Xinline-classes` 來選擇使用這項實驗性的特性。 ### 在 Gradle 中啟用內聯類 ``` groovy compileKotlin { kotlinOptions.freeCompilerArgs += ["Xinline-classes"] } ``` 關于詳細信息,請參見[編譯器選項](http://www.kotlincn.net/docs/reference/using-gradle.html#%E7%BC%96%E8%AF%91%E5%99%A8%E9%80%89%E9%A1%B9)。關于[多平臺項目](http://www.kotlincn.net/docs/reference/whatsnew13.html#%E5%A4%9A%E5%B9%B3%E5%8F%B0%E9%A1%B9%E7%9B%AE)的設置,請參見[使用 Gradle 構建多平臺項目](http://www.kotlincn.net/docs/reference/building-mpp-with-gradle.html#%E8%AF%AD%E8%A8%80%E8%AE%BE%E7%BD%AE)章節。 ### 在 Maven 中啟用內聯類 ```xml <configuration> <args> <arg>-Xinline-classes</arg> </args> </configuration> ``` 關于詳細信息,請參見[指定編譯器選項](http://www.kotlincn.net/docs/reference/using-maven.html#%E6%8C%87%E5%AE%9A%E7%BC%96%E8%AF%91%E5%99%A8%E9%80%89%E9%A1%B9)。 ## 進一步討論 關于其他技術詳細信息和討論,請參見[內聯類的語言提議](https://github.com/Kotlin/KEEP/blob/master/proposals/inline-classes.md)
                  <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>

                              哎呀哎呀视频在线观看