- Kotlin進階實戰(zhàn)
- 沈哲 易龐宙編著
- 1106字
- 2022-07-27 18:28:02
2.1.2 函數(shù)
1.返回Unit的函數(shù)
跟Java不同,Kotlin沒有void,但是函數(shù)總會返回一個值。如果一個函數(shù)不返回任何類型的對象,那么該函數(shù)返回的是Unit類型。
例如:
fun printHello(): Unit { println("Hello World") }
Unit返回值可以被省略:
fun printHello() { println("Hello World") }
2.返回Nothing的函數(shù)
跟Unit相比,容易混淆的是Nothing。Unit會返回Unit的單例,而通過閱讀Nothing的源碼,發(fā)現(xiàn)它永遠都不會返回任何東西。

在Nothing的表達式之后,所有代碼都是無法執(zhí)行的。throw表達式的類型是一個特殊的類型Nothing。
下面定義的doForever函數(shù)返回Nothing類型,因此它后面打印的"done"語句永遠不會被執(zhí)行。

3.單表達式函數(shù)
當(dāng)函數(shù)返回單個表達式時,可以省略函數(shù)體的花括號,例如:
fun sum(x: Int=0, y: Int): Int { return x + y }
等價于:
fun sum(x: Int=0, y: Int): Int = x + y
它還等價于:
fun sum(x: Int=0, y: Int) = x + y
因為Kotlin可以通過編譯器來推斷該函數(shù)的返回類型。
4.成員函數(shù)
成員函數(shù)是指在類或?qū)ο髢?nèi)部定義的函數(shù),這一點跟Java中的概念是一致的。
5.局部函數(shù)(Local Function)
所謂局部函數(shù),是指在一個函數(shù)中定義另一個函數(shù)。有點類似于內(nèi)部類,局部函數(shù)可以訪問外部函數(shù)的局部變量,甚至是閉包。
例如下面的代碼,在validate函數(shù)中定義了validateInput函數(shù),validateInput函數(shù)用來進行字符串的校驗,幫助我們消除重復(fù)的代碼。另外,還定義了一個printPerson函數(shù),它也包含一個局部函數(shù)print()用于打印Person信息。print()函數(shù)直接訪問了它的外部函數(shù)printPerson()的局部變量。

6.尾遞歸函數(shù)
來自維基百科的定義:在計算機科學(xué)中,尾調(diào)用是指一個函數(shù)的最后一個動作是一個函數(shù)調(diào)用的情形,即這個調(diào)用的返回值直接被當(dāng)前函數(shù)返回的情形。這種情形下稱該調(diào)用位置為尾位置。若這個函數(shù)在尾位置調(diào)用本身(或者一個尾調(diào)用本身的其他函數(shù)等),則稱這種情況為尾遞歸,是遞歸的一種特殊情形。尾調(diào)用不一定是遞歸調(diào)用,但是尾遞歸特別有用,也比較容易實現(xiàn)。
使用遞歸對自然數(shù)求和:

執(zhí)行上述代碼,會出現(xiàn)“Exception in thread "main" java.lang.StackOverflowError”。
這是因為在Kotlin中使用尾遞歸函數(shù)需要滿足兩個條件:
· 使用tailrec關(guān)鍵詞修飾函數(shù)。
· 在函數(shù)最后進行遞歸調(diào)用。
使用tailrec關(guān)鍵詞之后,編譯器會優(yōu)化該遞歸,從而避免堆棧溢出的風(fēng)險。
對上述代碼稍作修改:

此時,執(zhí)行結(jié)果如下:
705082704
而我們目前使用比較多的Java 8并不能在編譯器級別直接支持尾部調(diào)用優(yōu)化,只能通過Lambda方式實現(xiàn)。
7.Top level函數(shù)
相對于在Java中所有的內(nèi)容都必須在類中定義,Kotlin允許直接在.kt文件中定義任何類定義之外的top-level函數(shù)。
top-level函數(shù)的默認修飾符是public,因此這些函數(shù)可以在任何位置被訪問。例如定義如下的函數(shù):
@Throws(IOException::class) fun readFileToString(file: File): String = file.readText()
Java程序想要調(diào)用readFileToString()方法,必須通過文件名Kt.readFileToString(f)才可以調(diào)用。或者在文件頭添加:
@file:JvmName("FileUtils")
這樣一來,Java程序可以通過FileUtils.readFileToString(f)進行調(diào)用。
讓我們來小結(jié)一下Kotlin相關(guān)的top-level,如表2-1所示。
表2-1 Kotlin相關(guān)的top-level

8.無參的main函數(shù)
Kotlin程序的入口一般會采用main函數(shù),例如:
fun main(args: Array<String>) { println("Hello Kotlin") }
Kotlin 1.3之后引入了一種更簡單的無參main函數(shù),簡化了main函數(shù)的寫法:
fun main() { println("Hello Kotlin") }
- Software Defined Networking with OpenFlow
- Getting Started with ResearchKit
- C# Programming Cookbook
- Mastering SVG
- C#程序設(shè)計(慕課版)
- R語言游戲數(shù)據(jù)分析與挖掘
- Hands-On C++ Game Animation Programming
- Linux環(huán)境編程:從應(yīng)用到內(nèi)核
- Jenkins Continuous Integration Cookbook(Second Edition)
- C#實踐教程(第2版)
- Selenium Testing Tools Cookbook(Second Edition)
- Go語言精進之路:從新手到高手的編程思想、方法和技巧(2)
- Learning JavaScript Data Structures and Algorithms(Second Edition)
- Java Web應(yīng)用開發(fā)項目教程
- RESTful Web Clients:基于超媒體的可復(fù)用客戶端