22

while在 Java 中,我们通常可以在条件内执行赋值。然而,Kotlin 抱怨它。所以下面的代码无法编译:

val br = BufferedReader(InputStreamReader(
        conn.inputStream))

var output: String
println("Output from Server .... \n")
while ((output = br.readLine()) != null) { // <--- error here: Assignments are not expressions, and only expressions are allowed in this context
    println(output)
}

根据this other thread,这似乎是最好的解决方案:

val reader = BufferedReader(reader)
var line: String? = null;
while ({ line = reader.readLine(); line }() != null) { // <--- The IDE asks me to replace this line for while(true), what the...?
  System.out.println(line);
}

但是是吗?

4

6 回答 6

37

不,最好的方法,IMO,将是

val reader = BufferedReader(reader)
reader.lineSequence().forEach {
    println(it)
}

如果您想确保阅读器已正确关闭(就像您在 Java 中使用 try-with-resources 语句一样),您可以使用

BufferedReader(reader).use { r ->
    r.lineSequence().forEach {
        println(it)
    }
}
于 2017-01-08T20:54:25.127 回答
17

下面是Roman Elizarov的一个简短的 Kotlin 风格的通用解决方案:

while (true) {
    val line = reader.readLine() ?: break
    println(line);
}

Here breakhas Nothing类型也有助于促进lineas non-nullable 字符串的类型推断。

于 2017-04-22T10:05:10.890 回答
12

这是由stdlib提供支持的最短解决方案,它也可以安全地关闭阅读器:

reader.forEachLine {
    println(it)
}
于 2017-04-22T09:46:18.003 回答
3

如果您只想替换while ((x = y.someFunction()) != null),则可以使用以下内容:

generateSequence { y.someFunction() }
          .forEach { x -> /* what you did in your while */ }

generateSequence将一个一个地提取所有值,直到null达到第一个值。如果您想保留最后一个值或将这些值总结为其他值,您可以用.forEachor reduce(或其他任何似乎合适的东西 ;-)) 替换。fold

但是,对于您的特定用例,您可以只使用JB Nizet 在他的回答中显示或使用的内容useLines

reader.useLines {
  it.forEach(::println)
}

.forEachLine如果您知道您只想阅读所有行然后停止,则可能是该特定问题的下一个最佳速记解决方案(已在此处readLine回答)。

于 2019-01-31T09:06:36.787 回答
0

我发现这些天 IntelliJ 将您的 Java 代码转换为以下 kotlin 代码:

val br = BufferedReader(InputStreamReader(
        conn.inputStream))

var output: String
while (br.readLine().also { output = it } != null) {
    println(output)
}

这仍然令人困惑,但它的可读性很强。also它使用返回接收器实例的事实(br.readLine()此处的结果)。

于 2021-04-22T04:44:09.260 回答
-1

(此示例用于 while 循环)希望此示例对您有所帮助..

从改变

while ((c = is.read(buffer)) > 0) { sb.append(String(buffer, 0, c, Charset.forName(UTF8))) }

而 ({c = is.read(buffer);c}() > 0) { sb.append(String(buffer, 0, c, Charset.forName(UTF8))) }

于 2018-04-13T06:27:11.207 回答