Assignment not allowed in expression?

In Java, we can usually perform assignments as part of the while condition. However, Kotlin complains about this. Therefore, the following code does not compile:

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

According to this other thread, this seems like a better solution:

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

But this?

+15
source share
5 answers

No, the best way, IMO, would be

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

And if you want to make sure the reader is properly closed (as it would with the try-with-resources operator in Java), you can use

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

Here is the shortest stdlib- based solution that also safely closes the reader:

 reader.forEachLine { println(it) } 
+10
source

And here is a brief general solution in the style of Kotlin, Roman Elizarov:

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

Here break is of type Nothing , which does not affect type inference for line .

+10
source

In cases where you just want to replace while ((x = y.someFunction()) != null) you can use the following:

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

generateSequence will retrieve all values ​​one by one until the first null is reached. You can replace .forEach with reduce or fold (or anything else that seems appropriate ;-)) if you want to keep the last value or sum the values ​​elsewhere.

However, for your specific use case, you can simply use what JB Nizet showed in your answer , or use useLines :

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

.forEachLine is probably the next best shorthand solution for this particular readLine -problem (already answered here ), if you know that you just want to read all the lines and then stop.

0
source

(This example is for a while loop) Hope this example helps you ..

Vary from

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

in

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

-one
source

Source: https://habr.com/ru/post/1013886/


All Articles