在Kotlin中使用readLine获取字符串输入时出现错误



我是kotlin的初学者,这是我试图执行的代码,但是运行时错误正在显示。请帮我解决这个问题。

import java.util.*
fun main(args: Array<String>)
{
var inp = Scanner(System.`in`);
var t:Int = inp.nextInt();
repeat(t)
{
var n:Int = inp.nextInt();
var s:String = readLine()!!
for (i in s)
{
println(i);
}
println()

}
}

线程"main"异常芬兰湾的科特林。KotlinNullPointerExceptionProgKt.main (prog.kt: 10)这是显示的错误。

Smeki的答案是正确的,但是我需要指出一些事情,因为你是初学者,它可能会让你感到困惑。

通常你会这样做:

val s = readLine()

注意,您没有指定s类型-它是由您分配给它的任何内容推断出来的。因为readLine返回一个可空的String?,这是一个String可以为空(这是?在最后的意思),然后编译器知道s是一个String?。这相当于这样做:

val s: String? = readLine()

如果你愿意,你可以显式地这样做!不过你通常不需要这么做。现在你有了可空的s,你可以做一些空检查来安全地使用它:

if (s != null) {
// we know it's not null, so now you can do stuff with it
} else {
// if you like, you can handle the null case separately, like breaking out of 
// the loop (since null from readLine() means you've reached the end)
}

还有其他方法可以处理空值并进行空值检查-这里是关于它的文档,我将强烈建议你阅读它,并了解它——它是语言的关键部分!从长远来看,它使您的生活更轻松,代码更安全(避免了这样的问题!!!绕过null安全,这通常是一个坏信号)


还记得我说过可以显式声明s的类型吗?以下是我说的内容,以及你写的内容:

// correct
val s: String? = readLine()
// something's different!
val s: String = readLine()

看到你怎么错过了?,说它是一个可空类型?即使您计划在此之后对s进行空检查,它也会在这行处崩溃因为s被声明为非空类型,并且readLine()在某些时候将为null。当你将null赋值给非null变量时,它会崩溃并报错——因为就编译器而言,有些地方出了问题。

(你也应该得到一些警告在你的IDE中,如果你使用一个,尝试null检查一个变量,你已经声明为非空会给你一些"为什么你试图这样做?它不可能是空的,对吧?暗示某个地方出了问题的信息。此外,如果您没有在readLine()之后添加!!,则会收到有关此的警告-这可能是您首先添加!!的原因!它不会使问题消失,只是阻止IDE警告您)


你也可能已经注意到,我把s改成了val而不是var,因为它是一个固定的值,你不会改变-总是喜欢vals,除非你确实需要改变这个变量,这不是什么大问题,但它使其他一些事情更容易(你也会得到警告)

NPE最有可能是从

抛出的
var s:String = readLine()!!

where those !!是kotlin零安全功能的一部分。从readLine()的java文档中我们可以知道什么时候返回null。

/**
* Reads a line of input from the standard input stream.
*
* @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached.
*/
fun readLine(): String? = LineReader.readLine(System.`in`, Charset.defaultCharset())

相关内容

最新更新