while 表达式中不允许赋值?
Assignment not allowed in while expression?
在Java中我们通常可以在while
条件内进行赋值。但是 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)
}
根据另一个 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);
}
但是是吗?
不,IMO,最好的方法是
val reader = BufferedReader(reader)
reader.lineSequence().forEach {
println(it)
}
如果您想确保 reader 正确关闭(就像您在 Java 中使用 try-with-resources 语句一样),您可以使用
BufferedReader(reader).use { r ->
r.lineSequence().forEach {
println(it)
}
}
这是 stdlib 的最短解决方案 powered,它还可以安全地关闭 reader:
reader.forEachLine {
println(it)
}
这里是 Roman Elizarov 的 Kotlin 风格的简短通用 solution:
while (true) {
val line = reader.readLine() ?: break
println(line);
}
此处 break
具有 Nothing 类型,这也有助于将 line
的类型推断为不可空字符串。
(This Example for while loop )希望这个例子对你有帮助..
变化自
while ((c = is
.read(buffer)) > 0) {
sb.append(字符串(缓冲区, 0, c, Charset.forName(UTF8)))
}
至
while ({c = is
.read(buffer);c}() > 0) {
sb.append(字符串(缓冲区, 0, c, Charset.forName(UTF8)))
}
如果您只想替换 while ((x = y.someFunction()) != null)
,您可以使用以下代替:
generateSequence { y.someFunction() }
.forEach { x -> /* what you did in your while */ }
generateSequence
will extract you all the values one by one until the first null
is reached. You may replace the .forEach
with a reduce
or fold
(或其他任何看起来合适的东西 ;-))如果您想保留最后一个值或将这些值相加到其他值。
对于您的特定用例,您可以只使用 has shown or use useLines
:
reader.useLines {
it.forEach(::println)
}
.forEachLine
is probably the next best short-hand solution to that specific readLine
-problem (already answered ) 如果你知道你只想阅读所有行然后停止。
我发现最近 IntelliJ 将您的 Java 代码转换为以下 kotlin 代码:
val br = BufferedReader(InputStreamReader(
conn.inputStream))
var output: String
while (br.readLine().also { output = it } != null) {
println(output)
}
这仍然令人困惑,但可读性很强。它使用 also
returns 接收器实例(此处 br.readLine()
的结果)这一事实。
在Java中我们通常可以在while
条件内进行赋值。但是 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)
}
根据另一个 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);
}
但是是吗?
不,IMO,最好的方法是
val reader = BufferedReader(reader)
reader.lineSequence().forEach {
println(it)
}
如果您想确保 reader 正确关闭(就像您在 Java 中使用 try-with-resources 语句一样),您可以使用
BufferedReader(reader).use { r ->
r.lineSequence().forEach {
println(it)
}
}
这是 stdlib 的最短解决方案 powered,它还可以安全地关闭 reader:
reader.forEachLine {
println(it)
}
这里是 Roman Elizarov 的 Kotlin 风格的简短通用 solution:
while (true) {
val line = reader.readLine() ?: break
println(line);
}
此处 break
具有 Nothing 类型,这也有助于将 line
的类型推断为不可空字符串。
(This Example for while loop )希望这个例子对你有帮助..
变化自
while ((c = is
.read(buffer)) > 0) {
sb.append(字符串(缓冲区, 0, c, Charset.forName(UTF8)))
}
至
while ({c = is
.read(buffer);c}() > 0) {
sb.append(字符串(缓冲区, 0, c, Charset.forName(UTF8)))
}
如果您只想替换 while ((x = y.someFunction()) != null)
,您可以使用以下代替:
generateSequence { y.someFunction() }
.forEach { x -> /* what you did in your while */ }
generateSequence
will extract you all the values one by one until the first null
is reached. You may replace the .forEach
with a reduce
or fold
(或其他任何看起来合适的东西 ;-))如果您想保留最后一个值或将这些值相加到其他值。
对于您的特定用例,您可以只使用 useLines
:
reader.useLines {
it.forEach(::println)
}
.forEachLine
is probably the next best short-hand solution to that specific readLine
-problem (already answered
我发现最近 IntelliJ 将您的 Java 代码转换为以下 kotlin 代码:
val br = BufferedReader(InputStreamReader(
conn.inputStream))
var output: String
while (br.readLine().also { output = it } != null) {
println(output)
}
这仍然令人困惑,但可读性很强。它使用 also
returns 接收器实例(此处 br.readLine()
的结果)这一事实。