1 Java 中的 void 和 Kotlin 中的 Unit
在 Java 中,如果定義的函數(shù)沒有返回值,就需要用 void 來修飾,即 void 不可以省略。這也在 Java 中不能說函數(shù)調(diào)用皆是表達式的原因,因為有些方法不具有返回值和類型信息,就不能算作是表達式。
Java 在語言層設(shè)計一個 Void 類。java.lang.Void 類類似于 java.lang.Integer,Integer 是為了對基本類型 int 的實例進行裝箱操作。Void 的設(shè)計則是為了對應(yīng) void。由于 void 表示沒有返回值,所以,Void 并不能具有實例,它繼承自 Object。
在 Kotlin 中,函數(shù)在所有的情況下都有返回值類型,所以 Kotlin 引入了 Unit 來代替 Java 中的 void 關(guān)鍵字。
Unit 和 int 一樣,都是一種類型,然而,Unit 不代表任何信息。那么,Kotlin 為什么要引入 Unit 呢?很大一個原因是函數(shù)式編程。
在 Kotlin 中,對象或者函數(shù)都有類型,如果方法的返回類型是 Unit 時,可以省略。
對比:
- Java 中的 void 表示什么都不返回,Kotlin 中的 Unit 是一個真實的數(shù)據(jù)類型;
- Java 中的 void 是一個關(guān)鍵字,Kotlin 中的 Unit 是一個類;
2 Any 和 Any? : 根類型
和 Object 作為 Java 類層級結(jié)構(gòu)的根差不多,Any 類型是 Kotlin 所有非空類型的超類型(非空類型的根)。
但是在 Java 中,Object 只是所有引用類型的超類型(引用類型的根),而基本數(shù)據(jù)類型并不是類層級結(jié)構(gòu)的一部分。這意味著當我們需要 Object 的時候,不得不使用像 java.lang.Integer 這樣的包裝類型來表示基本數(shù)據(jù)類型的值。
而在 Kotlin 中,Any 是所有類型的超類型(所有類型的根),包括像 Int 這樣的基本數(shù)據(jù)類型。
和 Java 一樣,把基本數(shù)據(jù)類型的值賦給 Any 類型的變量時會自動裝箱:
val answer: Any = 42 // Any 是引用類型,所以值 42 會被裝箱
注意 Any 是非空類型,所以 Any 類型的變量不可以持有 null 值。在 Kotlin 中如果我們需要可以持有任何可能值的變量,包括 null 在內(nèi),必須使用 Any? 類型。
在底層,Any 類型對應(yīng) java.lang.Object。Kotlin 把 Java 方法參數(shù)和返回類型中用到的 Object 類型看作 Any。當 Kotlin 函數(shù)使用 Any 時,它會被編譯成 Java 字節(jié)碼中的 Object。
所有的 Kotlin 類中都包含:toString、equals 和 hashCode。這些方法都繼承自 Any。Any 并不能使用其他 java.lang.Object 的方法(比如 wait 和 notify),但是可以通過手動把值轉(zhuǎn)換成 java.lang.Object 來調(diào)用這些方法。
3 Nothing 類型:這個函數(shù)永不返回
對于某些 Kotlin 函數(shù)來說,“返回類型”的概念沒有任何意義,因為它們不會成功地結(jié)束。 例如,許多測試庫都有一個叫做 fail 的函數(shù),它通過拋出帶有特定消息的一場來讓當前測試失敗。一個包含無限循環(huán)的函數(shù)也永遠不會成功地結(jié)束。
當調(diào)用這樣的函數(shù)代碼時,知道函數(shù)永遠不會正常終止是很有幫助的。Kotlin 使用一種特殊的返回類型 Nothing 來表示:
fun main() {
fail("Error occurred")
}
fun fail(message: String): Nothing {
throw java.lang.IllegalStateException(message)
}
// Exception in thread "main" java.lang.IllegalStateException: Error occurred
// at com.ixuea.test.TestKt.fail(Test.kt:158)
// at com.ixuea.test.TestKt.main(Test.kt:152)
// at com.ixuea.test.TestKt.main(Test.kt)
Nothing 類型沒有任何值,只有被當作函數(shù)返回值使用,或者被當作泛型函數(shù)返回值的類型參數(shù)使用才會有意義。在其他所有情況下,聲明一個不能存儲任何值的變量沒有任何意義。
Nothing 是沒有任何實例的類型,Nothing 類型的表達式不會產(chǎn)生任何值。需要注意的是,任何返回值為 Nothing 的表達式之后的語句都是無法執(zhí)行的。這里有點像 return 或者 break 的作用。在 Kotlin 中 return、throw 等,返回值都是 Nothing。
注意,返回 Nothing 的函數(shù)可以放在 Elvis 運算符的右邊來做先決條件檢查:文章來源:http://www.zghlxwxcb.cn/news/detail-843108.html
val address = company.address ?: fail("No address")
println(address.city)
上面這個例子展示了在類型系統(tǒng)中擁有 Nothing 為什么極其有用。編譯器知道這種返回類型的函數(shù)從不正常終止,然后在分析調(diào)用這個函數(shù)的代碼時利用這個信息。在上面的例子中,編譯器會把 address 的類型推斷成非空,因為它為 null 時的分支處理會始終拋出異常。文章來源地址http://www.zghlxwxcb.cn/news/detail-843108.html
到了這里,關(guān)于Java 中的 void 和 Kotlin 的 Unit的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!