溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

發(fā)布時(shí)間:2020-09-20 20:10:10 來源:腳本之家 閱讀:248 作者:天命劍主 欄目:編程語言

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

在Java中可以使用{}建立一個(gè)匿名的代碼塊,代碼塊會(huì)被正常的執(zhí)行,除了改變了作用域之外,似乎并沒有什么其他的作用。然而在Kotlin中卻不能這么做,這是為什么呢?

其實(shí),我們都知道一個(gè)函數(shù)一定與一個(gè)內(nèi)存地址相關(guān),而一個(gè)匿名的代碼塊其實(shí)也相當(dāng)于是一個(gè)匿名的函數(shù)。在Kotlin中一般使用run函數(shù)來運(yùn)行一段匿名代碼塊。

如下:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

在Kotlin中使用標(biāo)識(shí)符后跟@符號(hào)來定義一個(gè)標(biāo)簽,使用@后跟標(biāo)識(shí)符來引用一個(gè)標(biāo)簽,run函數(shù)的語法初看起來似有一些怪異,其實(shí)run函數(shù)以一個(gè)函數(shù)作為參數(shù),而一個(gè)匿名的代碼塊就可以是一個(gè)匿名函數(shù),當(dāng)我們?cè)贗ntelliJ IDEA中把鼠標(biāo)光標(biāo)放到匿名代碼塊的大括號(hào)上時(shí),會(huì)顯示出匿名代碼塊對(duì)應(yīng)的函數(shù)簽名

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

如圖:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

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

由此可見,run函數(shù)的參數(shù),那段匿名代碼塊被編譯器轉(zhuǎn)換為了一個(gè)匿名函數(shù)是毫無疑問的。

當(dāng)然run函數(shù)是可以有返回值的,所以匿名代碼塊也可以是有返回值的匿名函數(shù)。

每一個(gè)函數(shù)都與一個(gè)或多個(gè)地址相對(duì)應(yīng),而每一個(gè)標(biāo)簽Label也是與一個(gè)或多個(gè)地址相對(duì)應(yīng),所以函數(shù)本身即是標(biāo)簽。

所以可以使用return@run之類的語法。

匿名函數(shù)雖然沒有函數(shù)名,然而我們可以定義一個(gè)具名標(biāo)簽來代表這個(gè)函數(shù),于是可以使用return@outer 2將2返回給i。

也許有人會(huì)有疑問,為什么不直接使用return 2呢,原因是return 將會(huì)從fun_run函數(shù)返回,而不是從匿名函數(shù)返回。

關(guān)于return和函數(shù)嵌套定義的問題下面還會(huì)說。

這段代碼的運(yùn)行結(jié)果如下:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

接下來說一說forEach函數(shù),與其他語言中不同,在Kotlin中forEach并不是一種語法,而是一類函數(shù),forEach是iterator的函數(shù),任何實(shí)現(xiàn)了iterator的類都可以使用forEach。forEach函數(shù)的參數(shù)也是一個(gè)函數(shù),其參數(shù)是一個(gè)模板函數(shù),可以是具名函數(shù),匿名函數(shù),lambda。forEach會(huì)對(duì)iterator迭代的每一個(gè)元素都調(diào)用一次傳入的函數(shù)。

之所以講到forEach,是為了熟悉標(biāo)簽的用法和return的用法。

如下:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

別忘了infix function call。

運(yùn)行結(jié)果如下:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

接下來說一說function type,討論一下函數(shù)。

對(duì)程序員來說,函數(shù)是很熟悉的,然而我們對(duì)函數(shù)就真的那么熟悉么?

函數(shù)也可以是類型,可以是變量,甚至常量。

如下:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

在這段代碼中我們定義了幾個(gè)函數(shù)類型的變量和常量,并且在之間進(jìn)行賦值等操作,其實(shí)和C++中的函數(shù)指針很相似,但是也有獨(dú)特的地方。比如嵌套函數(shù)定義,函數(shù)標(biāo)簽的引用以及帶標(biāo)簽的返回值等等。我們也看到了在一個(gè)匿名函數(shù)(end1代表的那個(gè))中如何使用lambda表達(dá)式定義函數(shù)的參數(shù)列表和自動(dòng)判斷的返回類型。

這段代碼運(yùn)行結(jié)果如下:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

剛才我們提到了函數(shù)嵌套定義,這是一個(gè)需要小心的地方。

看如下的代碼:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

從Java/C++一系出身的程序員(比如我:))很容易把這里的嵌套函數(shù)定義看成是匿名代碼塊的嵌套,以為程序會(huì)從外往內(nèi)執(zhí)行。從Pascal/PL一系出身的程序員就不會(huì)有這種問題,千萬記住,函數(shù)雖然可以嵌套定義,但是如果沒有調(diào)用是不會(huì)從外向內(nèi)執(zhí)行的。

所以輸出很簡(jiǎn)單:

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

我們也看到了return的用法,這里的f1,f2,f3雖然是內(nèi)部定義的函數(shù),但是依然可以作為標(biāo)簽使用。

可見Kotlin是一種集大成的語言,甚至借鑒了古老的unix腳本和Pascal的語法,借鑒了很多語言的特性,再加上強(qiáng)大的編譯器(Kotlin編譯器會(huì)幫你做很多東西,遠(yuǎn)比其他語言做的多得多),使Kotlin的代碼非常簡(jiǎn)潔優(yōu)雅而且編程相當(dāng)靈活高效。

在Kotlin中,太多的功能都是通過使用函數(shù)作為參數(shù)來實(shí)現(xiàn),有的已經(jīng)不能叫做語法,然而函數(shù)嵌套,infix function call,lambda,函數(shù)參數(shù),可變參數(shù)列表,靈活的標(biāo)簽,強(qiáng)大的return,自動(dòng)類型判斷,Range,iterator,操作符重載,省略,模板...這些太多的功能,導(dǎo)致Kotlin的語法眼花繚亂,雖然有時(shí)看起來很優(yōu)雅,但是也可能給人閱讀代碼帶來巨大的困難。

最后以一段沒什么卵用的代碼結(jié)束本篇。

Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI