從forEach理解一下kotlin的inline
在 Android 開發中有很多語法糖 , 其中 for Each 可以替代 for 迴圈 ,簡潔 的語法是很常用的
tempList.forEach { Timber.d("print list value =>${it}") }
在使用 for Each 時 , 相信每個開發者都會踩的一個坑就是 for Each 中的 return@forEach 無法直接退出 forEach
tempList.forEach { if (it == ""){ return@forEach } Timber.d("print list value =>${it}") }
先說個最常見的解決方案 , 在外層包一個 run , 然後使用 return@run 退出即可
run{ tempList.forEach { if (it == ""){ return@run } Timber.d("print list value =>${it}") } }
那麼為什麼 for Each 不能直接退出呢 ? 這就要從 kotlin 中有個非常好用的關鍵字 inline 說起 , 它可以幫你對做了標記的函式進行內聯最佳化。所謂內聯就是,呼叫的函式在編譯的時候會變成程式碼內嵌的形式
fun test(){ testInline() } private inline fun testInline(){ Timber.d("testInline") } //等於 fun test(){ Timber.d("testInline") }
在 kotlin 中方法也是變數 , 所以這樣做的區別在於 , 不實用 inline 每次呼叫會多建立一個變數 , 在頻繁的呼叫時 , 例如 for 迴圈中 , 記憶體的開銷會變得很大
這也解釋了 for Each 為什麼要使用 inline
如果針對其中某個引數不需要 inline 可以使用 no Inline , 效果如下
inline fun test1(first:()->Unit,noinline second:()->Unit){ first() Timber.d("3") second() } fun main(){ test1({ Timber.d("1") },{ Timber.d("2") }) }
等於
fun main(){ Timber.d("1") Timber.d("3") ({ Timber.d("2") }) }
這裡面有個坑 , 我們前面提到 , kotlin 中方法也是變數 , 所以在實際使用中 , 就可以加上 noInline 來返回該方法
inline fun test1(first:()->Unit, noinline second:()->Unit): () -> Unit { first() Timber.d("3") return second }
如果不加上 no Inlie
這是因為這時實際編譯結果是
fun main(){ Timber.d("1") Timber.d("3") Timber.d("2") second }
可以看到最後突兀的出現一個 second
除了 no Inline 還有個 crossInline , 剛才講的 noinline 是區域性關閉內聯最佳化 , 而這個 crossinline ,是區域性加強內聯最佳化
再看一下例子
inline fun test1(first:()->Unit) { first() Timber.d("2") } fun main(){ test1{ Timber.d("1") return } }
當我在使用行內函數時在裡面呼叫了 return , 因為使用內聯 , 方法到最後是展開的 , 也就是
fun main(){ Timber.d("1") Timber.d("2") return }
所以 , 他的本質是結束 mai n 函式 , 而不是隻結束 test 1 函式
如果將 test 1 中 first 的呼叫放在主執行緒中
可以看到系統提示要使用 cross Inline , 在使用之後 , 就會告訴不允許在 mai n 當中這樣使用 , main 當中只能 return @ test 1
所以什麼時候需要 crossinline?當你需要突破行內函數的「不能間接呼叫引數」的限制的時候。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/69917874/viewspace-3007312/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Kotlin inline noinline crossinline 解答KotlininlineROS
- 從Java角度深入理解KotlinJavaKotlin
- Kotlin邊用邊學:Inline Functions的適用場景KotlininlineFunction
- [譯]Kotlin中內聯類(inline class)完全解析(一)Kotlininline
- 我理解的foreach, for in, for of 之間的異同
- 深入理解PHP之foreachPHP
- Inline行內函數簡單理解inline函數
- inline: 我的理解還停留在20年前inline
- 理解 Kotlin 中的屬性(property)Kotlin
- 解釋一下 Kotlin 的 var、val、constKotlin
- IL角度理解for 與foreach的區別——迭代器模式模式
- 從自身成長聊一下我理解的“終身學習”
- 從 Java 到 Kotlin - 介紹 KotlinJavaKotlin
- 來入門一下kotlin吧Kotlin
- 易用版Popupwindow by Kotlin瞭解一下Kotlin
- [譯]Effective Kotlin系列之探索高階函式中inline修飾符(三)Kotlin函式inline
- Jetbrains開發者日見聞(三)之Kotlin1.3新特性(inline class篇)AIKotlininline
- 從Java到Kotlin(八)JavaKotlin
- 從Java到Kotlin(七)JavaKotlin
- 從Kotlin的類開始說起Kotlin
- gnu inline asminlineASM
- kotlin之plus、copyOf、reverse、forEach、filter、map、reduce、fold等函式解釋和使用KotlinFilter函式
- CSS display顯示分別為block、 inline、 inline-block的三種元素CSSBloCinline
- Kotlin 字串教程:深入理解與使用技巧Kotlin字串
- 充分理解Kotlin,快速上手寫業務Kotlin
- 在lambda的foreach遍歷中break退出(lambda foreach break)
- foreach使用引用時的一個坑-foreach原始碼分析原始碼
- Kotlin從入門到跑路(一)Kotlin
- inline、const、mutable、this、staticinline
- Mybatis中foreach的使用MyBatis
- php中foreach的使用PHP
- 你說一下對Java中的volatile的理解吧Java
- Kotlin直接使用控制元件ID原理解析Kotlin控制元件
- Iterator & foreach
- foreach陷阱
- JavaScript forEach()JavaScript
- Gradle指南之從Groovy遷移到KotlinGradleKotlin
- 從 simplemde 寫入 + inline-attachment 圖片拖拽上傳 到 parsedown 解析inline