表达时不允许分配?

时间:2017-01-08 20:40:16

标签: kotlin kotlin-interop

在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);
}

但是吗?

6 个答案:

答案 0 :(得分:26)

不,最好的方式,IMO,

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

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

BufferedReader(reader).use { r ->
    r.lineSequence().forEach {
        println(it)
    }
}

答案 1 :(得分:10)

以下是stdlib提供的最短解决方案powered,它也安全地关闭了读者:

reader.forEachLine {
    println(it)
}

答案 2 :(得分:10)

这是罗马伊丽莎白的短Kotlin式将军solution

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

此处break的{​​{3}}类型不会影响line的类型推断。

答案 3 :(得分:0)

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

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

generateSequence将一个一个地提取所有值,直到到达第一个null。如果要保留最后一个值或将这些值汇总为其他值,则可以用.forEachreduce(或其他任何合适的方法;-)代替fold

但是对于您的特定用例,您可以只使用JB Nizet in his answer所示的内容或使用useLines

reader.useLines {
  it.forEach(::println)
}
如果您知道只想阅读所有行然后停下来,那么

.forEachLine可能是该特定readLine问题(已经回答here)的次佳速记解决方案。

答案 4 :(得分: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() 的结果)这一事实。

答案 5 :(得分:-1)

(这个例子用于while循环)希望这个例子可以帮助你..

改变

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

while({c = is。read(buffer); c}()&gt; 0){             sb.append(String(buffer,0,c,Charset.forName(UTF8))) }