<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之旅 廣告
                ## 前言 **使用高階函數(higher-order functions)會導致一些性能的損耗:每個函數都是對象,且會捕獲閉包closure(即變量會在函數體內被訪問),函數對象/類會增加內存分配,而且虛擬調用棧也會增加額外內存開銷!** **可用內聯函數(inline function)消除這些額外內存開銷,說白了就是在調用處插入函數體代碼,以此減少新建函數棧和對象的內存開銷!被inline修飾的函數或lambda表達式,在調用時都會被內聯(在調用處插入函數體代碼)**。 [TOC] ## 內聯函數 **在Kotlin語法中,Lambda表達式都會被編譯成一個匿名類**。這樣的話**每次調用Lambda表達式時,就會創建出新的對象,造成額外的內存開銷,導致程序效率降低,為了解決這個問題,Kotlin中提供了一個修飾符“inline”,被inline修飾的Lambda(函數)稱為內聯函數,使用內聯函數可以降低程序的內存消耗,`inline`修飾符影響函數本身和傳給它的 lambda 表達式:所有這些都將內聯到調用處**。說白了**就是在調用處插入函數體代碼,以此減少新建函數棧和對象的內存開銷!被inline修飾的函數或lambda表達式,在調用時都會被內聯(在調用處插入函數體代碼)**。 本節將針對Kotlin中的內聯函數進行學習。 ### 使用內聯函數 在Kotlin中,**被“inline”修飾符修飾的Lambda(函數)稱為內聯函數**,使用內聯函數可以**降低程序的內存消耗,但內聯函數要合理使用,不要內聯一個復雜功能的函數,尤其在循環中**。接下來讓我們通過一個案例來學習內聯函數,具體代碼如下所示。 ``` import java.util.concurrent.locks.Lock import java.util.concurrent.locks.ReentrantLock inline fun <T> check(lock: Lock, body: () -> T): T { lock.lock() try { return body() } finally { lock.unlock() } } fun main(args: Array<String>) { var l = ReentrantLock() check(l, { print("這是內聯函數方法體") })//l是一個Lock對象 } ``` 運行結果: ``` 這是內聯函數方法體 ``` 在上述代碼中,**通過inline關鍵字指定check()函數就是一個內聯函數。在調用內聯函數時,編譯器會對`check(l, { print("這是內聯函數方法體") })`這句代碼優化,去掉方法名稱以避免入棧出棧操作,直接執行方法體內的內容**。具體代碼如下: ``` lock.lock() try { return "這是內聯函數方法體" } finally { lock.unlock() } } ``` 通過上述代碼可以看出,**內聯函數實際上在運行期間會增加代碼量,但對程序可讀性不會造成影響,同時也提升了性能**。 >[info]**注意**:內聯可能導致生成的代碼增加;不過如果我們使用得當(即避免內聯過大函數),性能上會有所提升,尤其是在循環中的“超多態(megamorphic)”調用處。 ### 禁用內聯函數 目前我們已經知道**當使用內聯函數時,參數也都會隨之內聯**,此時便會出現一個問題,**如果內聯函數的有些(作為參數)lambda表達式不是內聯,可用noinline修飾符函數參數!或者如果希望只內聯一部分傳給內聯函數的 lambda 表達式參數,那么可以用`noinline`修飾符標記不希望內聯的函數參數**: ~~~ inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { …… } ~~~ 就是**如果參數有Lambda表達式時,Lambda表達式便不是一個函數的對象(lambda表達式也就不能在調用處直接被插入),從而也就無法當作參數來傳遞。為了解決這個問題,可以使用noinline修飾符來修飾參數,禁止參數產生內聯關系**。 **可以內聯的 Lambda 表達式只能在內聯函數內部調用或者作為可內聯的參數傳遞, 但是 noinline 的可以以任何我們喜歡的方式操作:存儲在字段中、傳送它等等**。 接下來我們通過一個案例來演示,具體代碼如下所示。 ``` inline fun check(noinline function: (Int) -> Boolean){ test(function) } fun test(function: (Int) -> Boolean){ println("編譯通過") } fun main(args: Array<String>) { check { x : Int -> x == 2 } } ``` 運行結果: ``` 編譯通過 ``` 從運行結果可以看出,**通過noinline修飾的Lambda表達式是非內聯關系,可以當作參數使用**。 >[success]**注意**,如果一個內聯函數沒有可內聯的函數參數并且沒有[具體化的類型參數](http://www.kotlincn.net/docs/reference/inline-functions.html#%E5%85%B7%E4%BD%93%E5%8C%96%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%8F%82%E6%95%B0),編譯器會產生一個警告,因為內聯這樣的函數很可能并無益處(如果你確認需要內聯,則可以用 @Suppress("NOTHING_TO_INLINE") 注解關掉該警告)。
                  <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>

                              哎呀哎呀视频在线观看