如何使用 Kotlin 安全地转换 readLine() 的结果以防止类型不匹配

How to safely cast the result of readLine() to prevent a Type Mismatch using Kotlin

我看过/读过的很多Kotlin教程都有这行代码:

var number = Integer.valueOf(readLine())

虽然它以前显然有效,但现在在使用 Android studio 和 Kotlin 版本 1.3.50 时抛出编译器错误。 它表示类型不匹配,其中找到的是 String?,而要求的是 String

当然,我理解为什么会发生这种情况,我知道用户可以通过控制台传递 null 或空值,因此它需要有可选的 null 声明,但我想了解如何修复编译器错误并保持相似的代码而不改变太多。

虽然我可以使用这两行代码:

var number = Integer.valueOf(readLine()!!)

var number = Integer.valueOf(readLine() as String)

我相信这些可以引发不同的异常,如概述的那样

我知道我可以 'fix' 使用以下代码解决这个问题:

var number : String? = readLine();
if(number == null){
    number = "0"
}
val number2 = Integer.valueOf(number);

但这似乎非常低效。使用原生 Kotlin 代码是否有更短的方法?

如果我们简单地对 readLine() 的结果调用 toInt(),如果提供的值不是实际的整数,我们将得到一个异常。为了避免异常,我们可以使用 Kotlin 标准库中的 toIntOrNull()

val x= readLine()?.toIntOrNull() ?: 0

在这种情况下,我们读取该行(作为 String?),如果它不为空,则对其调用 toIntOrNull()。如果 that 不为空,我们就有了答案。否则,我们使用 0 作为默认值。

尽管我主要是 Swift 开发人员,但这是一个非常相似的概念。在 Swift 中它被称为 nil-coalescing 运算符,但显然在 Kotlin 中它被称为 Elvis 运算符(嗯嗯)。

文档是 here 所以你的代码应该是这样的:

var num : String = readLine() ?: "0";

如果 Elvis 运算符 ?: 之前的值不为空,则使用该值,否则使用您提供的第二个默认值。