Java 中的 void 和 Kotlin 的 Unit

news/2024/4/29 2:38:44

1 Java 中的 void 和 Kotlin 中的 Unit

在 Java 中,如果定义的函数没有返回值,就需要用 void 来修饰,即 void 不可以省略。这也在 Java 中不能说函数调用皆是表达式的原因,因为有些方法不具有返回值和类型信息,就不能算作是表达式。

Java 在语言层设计一个 Void 类。java.lang.Void 类类似于 java.lang.Integer,Integer 是为了对基本类型 int 的实例进行装箱操作。Void 的设计则是为了对应 void。由于 void 表示没有返回值,所以,Void 并不能具有实例,它继承自 Object。

在 Kotlin 中,函数在所有的情况下都有返回值类型,所以 Kotlin 引入了 Unit 来代替 Java 中的 void 关键字。

Unit 和 int 一样,都是一种类型,然而,Unit 不代表任何信息。那么,Kotlin 为什么要引入 Unit 呢?很大一个原因是函数式编程。

在 Kotlin 中,对象或者函数都有类型,如果方法的返回类型是 Unit 时,可以省略。

对比:

  • Java 中的 void 表示什么都不返回,Kotlin 中的 Unit 是一个真实的数据类型;
  • Java 中的 void 是一个关键字,Kotlin 中的 Unit 是一个类;

2 Any 和 Any? : 根类型

和 Object 作为 Java 类层级结构的根差不多,Any 类型是 Kotlin 所有非空类型的超类型(非空类型的根)。

但是在 Java 中,Object 只是所有引用类型的超类型(引用类型的根),而基本数据类型并不是类层级结构的一部分。这意味着当我们需要 Object 的时候,不得不使用像 java.lang.Integer 这样的包装类型来表示基本数据类型的值。

而在 Kotlin 中,Any 是所有类型的超类型(所有类型的根),包括像 Int 这样的基本数据类型。

和 Java 一样,把基本数据类型的值赋给 Any 类型的变量时会自动装箱:

val answer: Any = 42 // Any 是引用类型,所以值 42 会被装箱

注意 Any 是非空类型,所以 Any 类型的变量不可以持有 null 值。在 Kotlin 中如果我们需要可以持有任何可能值的变量,包括 null 在内,必须使用 Any? 类型。

在底层,Any 类型对应 java.lang.Object。Kotlin 把 Java 方法参数和返回类型中用到的 Object 类型看作 Any。当 Kotlin 函数使用 Any 时,它会被编译成 Java 字节码中的 Object。

所有的 Kotlin 类中都包含:toString、equals 和 hashCode。这些方法都继承自 Any。Any 并不能使用其他 java.lang.Object 的方法(比如 wait 和 notify),但是可以通过手动把值转换成 java.lang.Object 来调用这些方法。

3 Nothing 类型:这个函数永不返回

对于某些 Kotlin 函数来说,“返回类型”的概念没有任何意义,因为它们不会成功地结束。 例如,许多测试库都有一个叫做 fail 的函数,它通过抛出带有特定消息的一场来让当前测试失败。一个包含无限循环的函数也永远不会成功地结束。

当调用这样的函数代码时,知道函数永远不会正常终止是很有帮助的。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 类型没有任何值,只有被当作函数返回值使用,或者被当作泛型函数返回值的类型参数使用才会有意义。在其他所有情况下,声明一个不能存储任何值的变量没有任何意义。

Nothing 是没有任何实例的类型,Nothing 类型的表达式不会产生任何值。需要注意的是,任何返回值为 Nothing 的表达式之后的语句都是无法执行的。这里有点像 return 或者 break 的作用。在 Kotlin 中 return、throw 等,返回值都是 Nothing。

注意,返回 Nothing 的函数可以放在 Elvis 运算符的右边来做先决条件检查:

val address = company.address ?: fail("No address")
println(address.city)

上面这个例子展示了在类型系统中拥有 Nothing 为什么极其有用。编译器知道这种返回类型的函数从不正常终止,然后在分析调用这个函数的代码时利用这个信息。在上面的例子中,编译器会把 address 的类型推断成非空,因为它为 null 时的分支处理会始终抛出异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/10798.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

cannot find -xml2: No such file or directory的解决方法

一,问题现象 在编译库的时候出现如下图所示的报错:C:/msys64/mingw32/bin/…/lib/gcc/i686-w64-mingw32/13.2.0/…/…/…/…/i686-w64-mingw32/bin/ld.exe: ca nnot find -lxml2: No such file or directory collect2.exe: error: ld returned 1 exit s…

高性能 MySQL 第四版(GPT 重译)(三)

第八章:查询性能优化 在前几章中,我们解释了模式优化和索引,这对于高性能是必要的。但这还不够——您还需要设计良好的查询。如果您的查询不好,即使是设计最佳的模式和索引也不会表现良好。 查询优化、索引优化和模式优化是相辅…

【类脑智能】脑网络通信模型分类及量化指标(附思维导图)

脑网络通信模型分类及量化指标(附思维导图) 参考论文:Brain network communication_ concepts, models and applications 概念 脑网络通信模型是一种使用图论和网络科学概念来描述和量化大脑结构中信息传递的模型。这种模型可以帮助研究人员理解神经信号在大脑内…

智能合约语言(eDSL)—— 使用rust实现eDSL的原理

为理解rust变成eDSL的实现原理,我们需要简单了解元编程与宏的概念,元编程被描述成一种计算机程序可以将代码看待成数据的能力,使用元编程技术编写的程序能够像普通程序在运行时更新、替换变量那样操作更新、替换代码。宏在 Rust 语言中是一种功能&#x…

基于数据库的全文检索实现

对于内容摘要&#xff0c;信件内容进行全文检索 基于SpringBoot 2.5.6Postgresqljpahibernate实现 依赖 <spring-boot.version>2.5.6</spring-boot.version> <hibernate-types-52.version>2.14.0</hibernate-types-52.version><dependency><…

数字多空策略(实盘+回测+数据)

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…