Kotlin教程學習-Run,標籤Label,函數Function-Type

在Java中可使用{}創建一個匿名的代碼塊,代碼塊會被正常的執行,除了改變了做用域以外,彷佛並無什麼其餘的做用。然而在Kotlin中卻不能這麼作,這是爲何呢?程序員

其實,咱們都知道一個函數必定與一個內存地址相關,而一個匿名的代碼塊其實也至關因而一個匿名的函數。在Kotlin中通常使用run函數來運行一段匿名代碼塊。編程

以下:函數

在Kotlin中使用標識符後跟@符號來定義一個標籤,使用@後跟標識符來引用一個標籤,run函數的語法初看起來似有一些怪異,其實run函數以一個函數做爲參數,而一個匿名的代碼塊就能夠是一個匿名函數,當咱們在IntelliJ IDEA中把鼠標光標放到匿名代碼塊的大括號上時,會顯示出匿名代碼塊對應的函數簽名unix

local final fun <anonymous> ():Int defined in com.kotlin_learn.control_flow.fun_run指針

如圖:內存

local表明做用域,定義在函數內部,做用域僅爲local,final表明不可變,<anonymous>即爲匿名,()是參數列表,Int是返回值,com.kotlin_learn.control_flow.fun_run是函數定義位置的完整路徑。作用域

因而可知,run函數的參數,那段匿名代碼塊被編譯器轉換爲了一個匿名函數是毫無疑問的。編譯器

固然run函數是能夠有返回值的,因此匿名代碼塊也能夠是有返回值的匿名函數。it

每個函數都與一個或多個地址相對應,而每個標籤Label也是與一個或多個地址相對應,因此函數自己便是標籤。io

因此可使用return@run之類的語法。

匿名函數雖然沒有函數名,然而咱們能夠定義一個具名標籤來表明這個函數,因而可使用return@outer 2將2返回給i。

也許有人會有疑問,爲何不直接使用return 2呢,緣由是return 將會從fun_run函數返回,而不是從匿名函數返回。

關於return和函數嵌套定義的問題下面還會說。

這段代碼的運行結果以下:


接下來講一說forEach函數,與其餘語言中不一樣,在Kotlin中forEach並非一種語法,而是一類函數,forEach是iterator的函數,任何實現了iterator的類均可以使用forEach。forEach函數的參數也是一個函數,其參數是一個模板函數,能夠是具名函數,匿名函數,lambda。forEach會對iterator迭代的每個元素都調用一次傳入的函數。

之因此講到forEach,是爲了熟悉標籤的用法和return的用法。

以下:

別忘了infix function call。

運行結果以下:

接下來講一說function type,討論一下函數。

對程序員來講,函數是很熟悉的,然而咱們對函數就真的那麼熟悉麼?

函數也能夠是類型,能夠是變量,甚至常量。

以下:

在這段代碼中咱們定義了幾個函數類型的變量和常量,而且在之間進行賦值等操做,其實和C++中的函數指針很類似,可是也有獨特的地方。好比嵌套函數定義,函數標籤的引用以及帶標籤的返回值等等。咱們也看到了在一個匿名函數(end1表明的那個)中如何使用lambda表達式定義函數的參數列表和自動判斷的返回類型。

這段代碼運行結果以下:

剛纔咱們提到了函數嵌套定義,這是一個須要當心的地方。

看以下的代碼:

從Java/C++一系出身的程序員(好比我:))很容易把這裏的嵌套函數定義當作是匿名代碼塊的嵌套,覺得程序會從外往內執行。從Pascal/PL一系出身的程序員就不會有這種問題,千萬記住,函數雖然能夠嵌套定義,可是若是沒有調用是不會從外向內執行的。

因此輸出很簡單:


咱們也看到了return的用法,這裏的f1,f2,f3雖然是內部定義的函數,可是依然能夠做爲標籤使用。

可見Kotlin是一種集大成的語言,甚至借鑑了古老的unix腳本和Pascal的語法,借鑑了不少語言的特性,再加上強大的編譯器(Kotlin編譯器會幫你作不少東西,遠比其餘語言作的多得多),使Kotlin的代碼很是簡潔優雅並且編程至關靈活高效。

在Kotlin中,太多的功能都是經過使用函數做爲參數來實現,有的已經不能叫作語法,然而函數嵌套,infix function call,lambda,函數參數,可變參數列表,靈活的標籤,強大的return,自動類型判斷,Range,iterator,操做符重載,省略,模板...這些太多的功能,致使Kotlin的語法眼花繚亂,雖然有時看起來很優雅,可是也可能給人閱讀代碼帶來巨大的困難。

最後以一段沒什麼卵用的代碼結束本篇。

相關文章
相關標籤/搜索