標籤:

Kotlin傳教文 中(inline略解)

本文向您介紹Kotlin語言的一些奇特之處,方便您對Kotlin這門語言建立一個簡單的概念。

我就開門見山地接著上次的講了。

何為inline

相信寫過C系列語言的同學應該都十分熟悉inline這個修飾符了吧——而且好像不止C系列有inline。沒事這裡我繼續說說Kotlin的inline。本文篇幅非常短,因為inline是個很簡單的東西。

inline修飾符其實就是告訴編譯器,把這個方法的調用行為優化掉。怎麼優化呢?就是直接省掉調用行為,直接把方法的內容寫到調用的地方。但是Kotlin中的inline有所不同是,inline只能修飾含有單個block參數的方法。別的方法也可以用inline修飾,語法上不會報錯,但是如果你使用的IDE是IntelliJ IDEA,它會告訴你「nothing to inline」,並高亮提示。

然後這就是inline了。。你可以使用inline做這樣的事情:

// inline方法調用nlock(l) { foo() }nn// 普通的寫法nl.lock()ntry {n foo()n}nfinally {n l.unlock()n}n

是不是挺好的。。。

為什麼這種事情要inline來做呢?因為函數調用傳遞參數是需要消耗時間的。。。而且需要一層函數調用棧。。但是inline就把這些都省去了呢。。。

另外一個作用就是。。。

inline fun assWeCan(block: () -> Unit) {nt// codesn}nnfun boyNextDoor(block: () -> Unit) {nt// codesn}nnfun foo() {ntboyNextDoor {ntt// 這種寫法是不能通過編譯的,因為你不能從一個函數跳出另一個函數。你必須使用 return@assWeCan 或者 return@foo 這種寫法。nttreturnnt}ntassWeCan {ntt// 這種寫法可以通過編譯,因為你inline了之後就是直接從外部退出了。nttreturnnt}n}n

以上代碼在」Try Kotlin」上編譯通過。

所以啊,inline博大精深。

noinline和crossinline

那麼,noinline和crossinline又是什麼鬼呢。。。

其實inline這種東西啊,在一些比較奇怪的時候,會有各種各樣的問題啦。。比如各種東西的作用域啊。。Context不一樣啦。。。。所以Kotlin又弄了倆inline方法的Lambda參數的修飾符。

注意,inline是方法的修飾符,crossinline和noinline是參數的修飾符,而且僅限參數!

其實理解起來很簡單。請先仔細閱讀上文中的代碼。

crossinline

考慮如下代碼,這段代碼是編譯不過的。編譯器會提示你加個crossinline。

inline fun test(f: () -> Unit) {ntthread(f)n}n

這玩意強制編譯器把你的inline按照上述代碼中方法boyNextDoor的樣子處理(強制inline)。如果不能那樣處理的話就給個error,不通過編譯。很簡單吧。

比如以下代碼就不能通過編譯:

inline fun test(crossinline f: () -> Unit) {ntthread(block = f)nt// 你也可以這樣寫,下面這種寫法也不能通過編譯nt// thread(f)n}n

因為你進行了很不和諧的參數傳遞操作(其實只要是控制流都會出事),而如果把代碼inline進去的話是不行的。。自己想想如果把這個方法直接寫到原方法中的樣子吧。你只能這樣寫:

inline fun test(crossinline f: () -> Unit) {ntthread({ f() })n}n

noinline

這玩意不讓編譯器把你的inline按照上述代碼中方法boyNextDoor的樣子處理。如果那樣處理不能有任何效率/空間上的優化的話就給個warning,通過編譯。很簡單吧。

inline fun test(noinline f: () -> Unit) {n thread { f() }n}n

以上代碼你會收到一個可愛的warning。

因為這inline本來是個可以優化調用的操作,你非要寫成這樣就失去了inline的意義了(雖然不加noinline根本不過編譯(為什麼要這樣呢? 看下文)),所以警告一下啦。

Kotlin就是要求你寫的清晰。為了節約你的時間和精力,她幫你推斷類型。為了節約你的debug和code Review時間,她強制讓你聲明一些別的語言裡面不強制的東西(比如任何數值類型必須顯示cast,顯示聲明infix,顯示聲明tailrec,crossinline,noinline等等等等)。

像某些語言的隱式轉換啊,就是專門讓別人在不開debugger的情況下看不懂你的代碼的。。(逃

於是。。。

本垃圾說完了

嘛,就這樣啦。歡迎圍觀寒冰Frice全家桶:

  • Frice-JVM
  • Frice-CLR
  • Frice-Designer
  • Frice-Demo
  • Frice-DSL

求star求follow!QwQ

轉載自 如何讓孩子愛上Kotlin:DSL(中)


推薦閱讀:

關於C++11中移動語義的一個問題?何時移動構造函數會被調用?
工廠設計模式有什麼用?
遊戲設計模式(一) 序言:架構,性能與遊戲
7個有益的編程習慣
在 C++11 中,如何為匿名的結構體添加構造函數?

TAG:Kotlin | 编程 |