Kotlin中-Unit和Nothing

Kotlin中的Unit和Nothing

Unit

package kotlin

/**
 * The type with only one value: the `Unit` object. This type corresponds to the `void` type in Java.
 */
public object Unit {
    
    
    override fun toString() = "kotlin.Unit"
}

Kotlin里面的Unit在类型上相当于Java里面的void,但是又有些不同。

  • Java中的void是关键字。Unit本身是一个用 object 表示的单例,所以可以理解为Kotlin有一个类
  • 在Kotlin中,一切方法/函数都是表达式。表达式是总是有值的,所以每一个方法都必有一个返回值。如果没有用 return 明确的指定,那么一般来说就会用自动帮我们加上 Unit
fun method() :Unit{
    
    

}
fun method(){
    
    

}

上面的两个方法是相同的。:Unit是可以省略的。

Nothing

package kotlin

/**
 * Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
 * if a function has the return type of Nothing, it means that it never returns (always throws an exception).
 */
public class Nothing private constructor()

在Kotlin中,所有正常的方法都会有返回值,至少会有一个Unit返回,但是还有一种返回类型为Nothing的方法。这种方法是不正常的,或者说它会抛出异常。

凡事皆有实例。 你可以用Nothing来表示“一个从不存在的值”:例如: 如果函数的返回类型为Nothing,则意味着它永远不会返回(总是抛出异常)。

当我们定义一个函数,给出的返回类型是Nothing:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zapfdfoz-1687659149507)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230625095835948.png)]

可以看出直接编译就报错了,对于编译器来说,你明明告诉他返回值不存在,可以你还return了一个值,他直接emo了…

这时候我们应该是抛出一个异常。可以下面这样修改:

fun main() {
    
    
   method("抛出异常")
}

fun method(error:String) :Nothing{
    
    
    throw Exception(error)
}

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FYVwVVF4-1687659149509)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230625100217926.png)]

在Kotlin中类似的还有TODO: TODO 函数 唯一的作用 就是 抛出异常

fun test3(){
    
    
    TODO()
}

@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()

这个TODO函数可以在任何函数下抛出异常。不过如果你足够细心会发现test3() 方法返回值类型应该是默认的 Unit ,或者其他自己定义的返回类型,但实际上因为调用了 TODO() ,所以返回了一个 Nothing (并没有正常返回),这样编译是可以通过的,为什么呢?

有一些文章是把 Nothing 当做其他所有类的子类来理解的,也就是说 Nothing 是其他类的子类,所以返回其他类的地方可以用一个返回 Nothing 来代替,这样理解也是没问题的。但是就有疑问了,Kotlin&Java不是单继承的吗?如果 Nothing 是所有类的子类,那不就是多继承了?其实这里有一个概念。其实“继承”和“子类化”是两个概念,我们说类A继承了类B,即 A extends B,是强调B中的一些实现,可以在A中复用;而说类A是类B的子类,是强调在需要类B的地方可以用类A代替。两者的角度不一样。单继承,指的是从继承的角度上,一切类的顶级父类都是 Any (Java中是 Object ),那么大家都可以复用父类的现有实现。而子类化,则是在所有需要用到父类的地方可以代替,比如一个方法我需要返回一个 Any,那么我实际上返回一个 Int 对象,也是没问题的。所以说,Nothing 可以代替原方法的返回类型,是从子类化的角度,因为可代替,所以 Nothing 是所有类的子类,这和单继承是没冲突的。

猜你喜欢

转载自blog.csdn.net/qq_43867812/article/details/131371948