一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Kotlin中關于內聯函數的一些理解分享

Kotlin中關于內聯函數的一些理解分享

2022-03-10 15:25淚已無痕 Android

這篇文章主要給大家介紹了關于Kotlin中內聯函數的一些理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

看了很多博客,才明白了內聯的含義,其實最根本的就是將寫在別處的代碼拷貝到你現在執行的方法中,相當于在一個方法中執行,java的方法執行是需要壓棧出棧的對吧,如果是兩三個方法那就是兩三次的壓棧出棧,為了節省這個操作,提高一定的效率,kotlin就出了這么個函數。但又想想,如果是個超級大的函數,考來考去的也是很麻煩啊,所以這東西需要自己權衡吧,遵守單一職責,降低代碼圈發雜度才是根本。

內聯函數的理解

inline函數(內聯函數)從概念上講是編譯器使用函數實現的真實代碼來替換每一次的函數調用,帶來的最直接的好處就是節省了函數調用的開銷,而缺點就是增加了所生成字節碼的尺寸。基于此,在代碼量不是很大的情況下,我們是否有必要將所有的函數定義為內聯?讓我們分兩種情況進行說明:

  1. 將普通函數定義為內聯:眾所周知,JVM內部已經實現了內聯優化,它會在任何可以通過內聯來提升性能的地方將函數調用內聯化,并且相對于手動將普通函數定義為內聯,通過JVM內聯優化所生成的字節碼,每個函數的實現只會出現一次,這樣在保證減少運行時開銷的同時,也沒有增加字節碼的尺寸;所以我們可以得出結論,對于普通函數,我們沒有必要將其聲明為內聯函數,而是交給JVM自行優化。
  2. 將帶有lambda參數的函數定義為內聯:是的,這種情況下確實可以提高性能;但在使用的過程中,我們會發現它是有諸多限制的,讓我們從下面的例子開始展開說明:
?
1
2
3
4
5
inline fun doSomething(action: () -> Unit) {
 println("Before doSomething...")
 action()
 println("After doSomething...")
}

假如我們這樣調用doSomething:

?
1
2
3
4
5
fun main(args: Array<String>) {
 doSomething {
  pringln("Hello World")
 }
}

上面的調用會被編譯成:

?
1
2
3
4
5
fun main(args: Array<String>) {
 println("Before doSomething...")
 println("Hello World")
 println("After doSomething...")
}

從上面編譯的結果可以看出,無論doSomething函數還是action參數都被內聯了,很棒,那讓我們換一種調用方式:

?
1
2
3
4
fun main(args: Array<String>) {
 val action:() -> Unit = { println("Hello World") }
 doSomething(action)
}

上面的調用會被編譯成:

?
1
2
3
4
5
fun main(args: Array<String>) {
 println("Before doSomething...")
 action()
 println("After doSomething...")
}

doSomething函數被內聯,而action參數沒有被內聯,這是因為以函數型變量的形式傳遞給doSomething的lambda在函數的調用點是不可用的,只有等到doSomething被內聯后,該lambda才可以正常使用。

通過上面的例子,我們對lambda表達式何時被內聯做一下簡單的總結:

  • 當lambda表達式以參數的形式直接傳遞給內聯函數,那么lambda表達式的代碼會被直接替換到最終生成的代碼中。
  • 當lambda表達式在某個地方被保存起來,然后以變量形式傳遞給內聯函數,那么此時的lambda表達式的代碼將不會被內聯。

上面對lambda的內聯時機進行了討論,消化片刻后讓我們再看最后一個例子:

?
1
2
3
4
5
6
7
inline fun doSomething(action: () -> Unit, secretAction: () -> Unit) {
 action()
 doSomethingSecret(secretAction)
}
 
fun doSomethingSecret(secretAction: () -> Unit) {
}

上面的例子是否有問題?是的,編譯器會拋出“Illegal usage of inline-parameter”的錯誤,這是因為Kotlin規定內聯函數中的lambda參數只能被直接調用或者傳遞給另外一個內聯函數,除此之外不能作為他用;那我們如果確實想要將某一個lambda傳遞給一個非內聯函數怎么辦?我們只需將上述代碼這樣改造即可:

?
1
2
3
4
5
6
7
inline fun doSomething(action: () -> Unit, noinline secretAction: () -> Unit) {
 action()
 doSomethingSecret(secretAction)
}
 
fun doSomethingSecret(secretAction: () -> Unit) {
}

很簡單,在不需要內聯的lambda參數前加上noinline修飾符就可以了。

以上便是我對內聯函數的全部理解,通過掌握該特性的運行機制,相信大家可以做到在正確的時機使用該特性,而非濫用或因恐懼棄而不用。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.jianshu.com/p/678a49054238

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲福利一区二区 | 国产精品原创视频 | 四虎色影院 | 欧洲肥女大肥臀 | 国产成人精品曰本亚洲78 | 久久中文字幕无线观看 | 天堂激情网 | 热伊人99re久久精品最新地 | 爆操俄罗斯美女 | 日本动漫打扑克动画片樱花动漫 | videos变态极端 | 西西人体大胆啪啪私拍色约约 | 四虎一区 | 欧美ⅹxxxhd3d| 国产精品久久毛片蜜月 | sihu国产午夜精品一区二区三区 | 国内精品91久久久久 | 欧美粗黑巨大gay | 久热这里只有精品99国产6 | 成年视频在线观看 | 奇米888在线看奇米999 | 成人亚洲欧美日韩在线观看 | 国产绳艺在线播放 | hd在线观看免费高清视频 | 久久精品国产在热亚洲 | videojapan日本孕交孕 | 手机看片一区二区 | 男人把大ji巴放进男人免费视频 | 女人全身裸露无遮挡免费观看 | 精品福利一区 | 95视频在线观看在线分类h片 | 国产自产在线 | 国产亚洲精品一区二区在线播放 | 四虎免费影院ww4164h | 亚洲欧美一区二区三区在饯 | 超级毛片 | 免费港剧在线观看港剧 | 美女操穴视频 | 亚洲国产精品成人午夜在线观看 | 99精品国产综合久久久久 | 国产精品视频免费看 |