println(fruit as Apple)
//打印为 null,安全的类型转换
println(fruit as? Apple)
kotlin 类型Unit
、Nothing
和Nothing?
、Any
和Any?
区分
kotlin 中 Unit 类型与 java 中 void 的功能基本相似。如下是 kotlin 源码中 Unit 的源码:
//Unit 类型是一个 object 对象类型
public object Unit {
//toString 函数返回值
override fun toString() = “kotlin.Unit”
}
在 kotlin 中,当一个函数没有返回值时,我们用 Unit 来表示,而不是 null;大多数时候我们不需要显示地返回 Unit,或者声明一个函数的返回值是 Unit,编译器会自动推断它。跟 kotlin 的其他类型一样,Unit 的基类型是 Any。如果是一个可空的Unit?
则父类型是Any?
。Any?
是 Any 的超集,Any?
是 kotlin 类型层次的最顶端。
fun main() {
val unit = testUnit()
println(unit is Unit) //true
println(unit is Any) //true
println(unit is Unit?) //true
println(unit is Any?) //true
val unitNullable = testUnitNullable()
println(unitNullable is Unit) //false
println(unitNullable is Any) //false
println(unitNullable is Unit?) //true
println(unitNullable is Any?) //true
}
fun testUnit(): Unit {}
fun testUnitNullable(): Unit? { return null }
我们知道,在 java 中 void 不能是变量的类型,也不能作为值打印输出,java 提供了一个包装类 Void(void 的自动装箱类型),如果我们想让一个方法的返回类型永远是 null,则可以把返回类型定义为这个大写的 Void 类型。
java 中的这个 Void 类型对应 kotlin 的类型就是Nothing?
,在 kotlin 中可以理解为不可达,即不返回或者返回不可访问类型,是一种约定,Nothing 的类源码如下:
//外界无法创建 Nothing 实例
public class Nothing private constructor()
在 kotlin 中 throw 表达式的返回值就是 Nothing 类型的,表示了一种不可达(因为 throw 表达式执行完毕后就异常了,自然也就是不可达后续流程了),所以如果一个函数返回值是 Nothing,那么这个函数永远不会有返回值。譬如如下场景:
//因为 pick 永远不会反回值,而是直接抛出了异常,这个时候可以用 Nothing 作为 pick 函数的返回值
fun pick(index: Int): Nothing {
throw Exception()
}
所以 Unit 与 Nothing 的区别是,Unit 类型表达式计算结果返回值是 Unit,Nothing 类型表达式计算结果永远是不会反回的。
此外Nothing?
可以只包含一个值 null,Nothing?
唯一允许的值是 null,可被用作任何可空类型的空引用。譬如如下场景:
//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】
val test = null //编译器只能推断出类型为 Nothing?,空或者不可达类型
println(test is Nothing?) //true
val test1 = listOf(null) //编译器推断的类型为 List<Nothing?>
与 java 不同的是,kotlin 的变量类型可以是类似下面这样的(其实 groovy 也有类似部分特性):
//有返回值原始写法
fun count(arg1: Int, arg2: Int): Int {
return arg1 + arg2
}
//一行表达式简写
fun count2(arg1: Int, arg2: Int): Int = arg1 + arg2
//自动类型推断简写
fun count3(arg1: Int, arg2: Int) = arg1 + arg2
//无返回值原始写法
fun printCom(arg1: Int, arg2: Int): Unit {
println("$arg1 — $arg2")
}
//一行表达式简写
fun printCom1(arg1: Int, arg2: Int) = println("$arg1 — $arg2")
//自动类型推断简写
fun printCom2(arg1: Int, arg2: Int) {
println("$arg1 — $arg2")
}
java 中的 if 语句仅仅只能当作语句使用&#