Noting

Kotlin 是一种静态类型语言。这意味着每个 Kotlin 表达式在编译时都有已知的类型。

类型信息简化了类型检查、方法分发、性能优化等任务,也帮助开发者进行代码补全和错误诊断。

每个 Kotlin 函数都有返回类型。如果函数不返回任何值,其返回类型就是 Unit。这种做法确保了与 Java 的完全兼容性,并在没有返回值时提供更高的可预测性。但 Kotlin 的类型系统还引入了一个比静态类型更强的概念:Nothing。我们将在下一节中详细探讨 Nothing


Nothing

Kotlin 是一种静态类型的编程语言。例如,在 Kotlin 中定义变量时,必须显示或通过赋值来隐式地声明其类型:

val country: String = "United States" // 显式声明类型
val city = "New York" // 编译器推断出 String 类型

Kotlin 在编译时确保类型不匹配被捕获,减少了运行时错误的可能:

val number: Int = "1234" // 编译错误

在 Kotlin 中,Nothing 是一个非常特殊的类型,因为它没有任何实例。你可能会问这种类型有什么用?它可以用在**函数永远不会返回值(甚至不是 Unit)**的场景中。

本质上,Nothing 是 Kotlin 中所有类型的子类型,这意味着它可以出现在任何需要某种类型的地方。

例如,来看一个适合使用 Nothing 类型的例子:

fun fail(): Nothing {
    throw RuntimeException("This function always throws an exception")
}

fun calculatePercentage(marks: Int, total: Int): Float {
    if (total == 0) {
        fail()  // 在需要 Float 的地方使用了 fail()
    }
    return (marks / total.toFloat()) * 100
}

如果 total 是 0,就无法计算百分比。但此函数需要返回 Float 类型。我们不能返回 null(前提是不允许返回可空的 Float),也不能返回其他无意义的值。这时使用返回 Nothing 的函数是非常有效的方式。


异常与 Nothing

大多数编程语言通过异常处理错误。当程序中发生错误或意外事件时,会抛出异常。这种机制中,程序的执行流程会跳转到异常处理代码。Kotlin 也采用这种方式,并通过 Nothing 类型在类型系统中进一步加强。

Nothing 表示一个函数永远不会成功返回任何值。它意味着该函数总是抛出异常或中断程序执行。

来看一个例子:

fun fail() {
    throw Exception("This function always throws an exception")
}

fun greet() {
    fail() // 允许在期望 String 的位置调用 fail()
}

在上面的代码中,fail() 总是抛出异常,却用在一个本应返回 String 的函数中。由于 Nothing 是所有类型的子类型,编译器允许它出现在任何类型期望的位置。但请注意,你永远不会在运行时得到 String,因为 fail() 永远不会返回。

这种用法适用于在某些条件下必须失败的函数。虽然函数签名可能表明它会返回值,实际上它永远不会返回,而是始终抛出异常:

fun fail(): Nothing {
    throw RuntimeException("This function always throws an exception")
}

更多 Nothing 示例

抛出空指针异常的函数:

fun alwaysThrowsNPE(): Nothing {
    throw NullPointerException("Null pointer exception always thrown")
}

每次调用都会抛出空指针异常,因此不会返回值。

抛出非法参数异常的函数:

fun checkAge(age: Int): Nothing {
    throw IllegalArgumentException("Age cannot be negative: $age")
}

这个函数也从不返回。

一个永远不会返回的无限循环函数:

fun infiniteLoop(): Nothing {
    while (true) {
        // 无限循环,没有 return,也没有 break
    }
}

由于永远不会跳出循环,函数永远不会返回。使用 Nothing 表明这一点。

这使得开发者和编译器都能清楚地知道这些函数永远不会返回,可能抛出异常或永久阻塞,有助于编写更清晰可靠的代码。


TODO 函数

Kotlin 的标准库中提供了 TODO 函数,用于标记尚未实现的代码。它的函数签名如下:

fun TODO(reason: String): Nothing

它会抛出 NotImplementedError 异常,并使之后的代码不可达:

fun yetToImplementFeature(): String {
    TODO("Feature not implemented yet")
    println("This statement is unreachable") // 不会被执行
}

由于 TODO 返回 Nothing,你可以在任何需要值的地方使用它,例如:

// if-else 中
val x = if (expression) {
    TODO("Not decided what to do yet")
} else {
    // 其他情况
}

// 循环中
for (item in list) {
    TODO("Processing of the list items is not implemented yet")
}

注意 TODO 帮助你清晰地标记出未完成部分。


总结

Kotlin 是一门灵活而强大的语言,具备优秀的类型系统和错误检测能力。
其中 Nothing 类型提供了一种明确表达“永远不返回”的函数行为的方式,提升了代码可读性和安全性。
TODO 函数结合 Nothing 类型,清楚地标记出尚未实现的功能,是团队协作或大型项目中的好帮手。

Kotlin 通过这些设计增强了健壮性和开发体验。

AlarmManager: sending alarm Alarm{680e691 type 2 origWhen 4381192 whenElapsed 4381192 com.google.android.gms} uid 10111 whenElapsed 4381192 windowLength 3750 maxWhenElapsed 4384942 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 362: 06-22 22:27:30.100 1933 2190 V AlarmManager: sending alarm Alarm{680e691 type 2 origWhen 4381192 whenElapsed 4381192 com.google.android.gms} uid 10111 whenElapsed 4381192 windowLength 3750 maxWhenElapsed 4384942 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 362: 91 type 2 origWhen 4381192 whenElapsed 4381192 com.google.android.gms} uid 10111 whenElapsed 4381192 windowLength 3750 maxWhenElapsed 4384942 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 363: 06-22 22:27:30.101 1933 2190 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 1000 tag:*alar WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 363: 06-22 22:27:30.101 1933 2190 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 1000 tag:*alar WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 368: 06-22 22:27:31.886 1933 4499 W JobScheduler: Job didn't exist in JobStore: #com.google.android.apps.photos/1034 行 375: 06-22 22:27:34.047 1933 4482 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 376: 06-22 22:27:34.048 1933 4482 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 390: 06-22 22:27:41.331 1933 2106 W ProcessStats: Tracking association SourceState{61808ed com.google.android.googlequicksearchbox:search/10114 BFgs #37679} whose proc state 4 is better than process ProcessState{7befd9 com.google.android.adservices.api/10269 pkg=com.google.android.adservices.api} proc state 5 (5 skipped) 行 390: 06-22 22:27:41.331 1933 2106 W ProcessStats: Tracking association SourceState{61808ed com.google.android.googlequicksearchbox:search/10114 BFgs #37679} whose proc state 4 is better than process ProcessState{7befd9 com.google.android.adservices.api/10269 pkg=com.google.android.adservices.api} proc state 5 (5 skipped) 行 390: 06-22 22:27:41.331 1933 2106 W ProcessStats: Tracking association SourceState{61808ed com.google.android.googlequicksearchbox:search/10114 BFgs #37679} whose proc state 4 is better than process ProcessState{7befd9 com.google.android.adservices.api/10269 pkg=com.google.android.adservices.api} proc state 5 (5 skipped) 行 475: 06-22 22:27:54.782 1933 2694 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 10111 tag:Colle WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 475: 06-22 22:27:54.782 1933 2694 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 10111 tag:Colle WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 544: 06-22 22:27:56.734 1933 2694 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 545: 06-22 22:27:56.735 1933 2694 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 551: 06-22 22:27:56.971 1933 2010 I ActivityManager: Start proc 31669:com.google.android.apps.photos:mediametadataservice/u0a254 for service {com.google.android.apps.photos/com.google.android.apps.photos.mediametadataservice.MediaMetadataService} 行 551: 06-22 22:27:56.971 1933 2010 I ActivityManager: Start proc 31669:com.google.android.apps.photos:mediametadataservice/u0a254 for service {com.google.android.apps.photos/com.google.android.apps.photos.mediametadataservice.MediaMetadataService} 行 551: 06-22 22:27:56.971 1933 2010 I ActivityManager: Start proc 31669:com.google.android.apps.photos:mediametadataservice/u0a254 for service {com.google.android.apps.photos/com.google.android.apps.photos.mediametadataservice.MediaMetadataService} 行 555: 06-22 22:27:57.047 1933 1984 I ActivityManager: Killing 27828:com.google.android.apps.messaging/u0a230 (adj 905): empty #33 行 566: 06-22 22:27:58.351 1933 4504 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 567: 06-22 22:27:58.352 1933 4504 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 568: 06-22 22:28:00.576 1933 4514 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 569: 06-22 22:28:00.576 1933 4514 W UriGrantsManagerService: No permission grants found for com.google.android.apps.photos 行 578: 06-22 22:28:26.594 1933 2190 V AlarmManager: sending alarm Alarm{e486511 type 2 origWhen 4437684 whenElapsed 4437684 com.google.android.gms} uid 10111 whenElapsed 4437684 windowLength 3750 maxWhenElapsed 4441434 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 578: 06-22 22:28:26.594 1933 2190 V AlarmManager: sending alarm Alarm{e486511 type 2 origWhen 4437684 whenElapsed 4437684 com.google.android.gms} uid 10111 whenElapsed 4437684 windowLength 3750 maxWhenElapsed 4441434 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 578: 11 type 2 origWhen 4437684 whenElapsed 4437684 com.google.android.gms} uid 10111 whenElapsed 4437684 windowLength 3750 maxWhenElapsed 4441434 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 581: 06-22 22:28:26.606 1933 2694 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 10111 tag:Colle WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 581: 06-22 22:28:26.606 1933 2694 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 10111 tag:Colle WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 596: 06-22 22:28:58.407 1933 2190 V AlarmManager: sending alarm Alarm{31d0bff type 2 origWhen 4469495 whenElapsed 4469495 com.google.android.gms} uid 10111 whenElapsed 4469495 windowLength 3750 maxWhenElapsed 4473245 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 596: 06-22 22:28:58.407 1933 2190 V AlarmManager: sending alarm Alarm{31d0bff type 2 origWhen 4469495 whenElapsed 4469495 com.google.android.gms} uid 10111 whenElapsed 4469495 windowLength 3750 maxWhenElapsed 4473245 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 596: ff type 2 origWhen 4469495 whenElapsed 4469495 com.google.android.gms} uid 10111 whenElapsed 4469495 windowLength 3750 maxWhenElapsed 4473245 repeatInterval 0 action com.google.android.location.ALARM_WAKEUP_ACTIVITY_DETECTION component null flags 0x0 procName com.google.android.gms.persistent 行 597: 06-22 22:28:58.415 1933 4514 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 10111 tag:Colle WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 597: 06-22 22:28:58.415 1933 4514 D OplusProxyWakeLock: acquireProxyWakeLock failed, prevent uid: 10111 tag:Colle WorkSource{10111 com.google.android.gms, 10146 com.google.android.apps.maps, 10329 com.ixigo.train.ixitrain} result: TAG_ILLEGAL 行 599: 06-22 22:28:58.545 1933 4514 W AppOps : Noting op not finished: uid 10111 pkg com.google.android.gms code 79 startTime of in progress event=1750612543556 行 600: 06-22 22:28:58.555 1933 2981 W AppOps : Noting op not finished: uid 10111 pkg com.google.android.gms code 113 startTime of in progress event=1750612514999 行 601: 06-22 22:28:58.565 1933 2981 W AppOps : Noting op not finished: uid 10111 pkg com.google.android.gms code 113 startTime of in progress event=1750612514999 行 602: 06-22 22:28:58.573 1933 2981 W AppOps : Noting op not finished: uid 10111 pkg com.google.android.gms code 113 startTime of in progress event=1750612514999 行 603: 06-22 22:28:58.578 1933 4514 W AppOps : Noting op not finished: uid 10111 pkg com.google.android.gms code 113 startTime of in progress event=1750612525546
07-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值