34

Something in java like

int a = 1, b = 2, c = 1;
if ((a = b) !=c){
    System.out.print(true);
}

now it should be converted to kotlin like

var a:Int? = 1
var b:Int? = 2
var c:Int? = 1
if ( (a = b) != c)
    print(true)

but it's not correct.

Here is the error I get:

in " (a=b)" Error:(99, 9) Kotlin: Assignments are not expressions, and only expressions are allowed in this context

Actually the code above is just an example to clarify the problem. Here is my original code:

fun readFile(path: String): Unit { 
    var input: InputStream = FileInputStream(path) 
    var string: String = "" 
    var tmp: Int = -1 
    var bytes: ByteArray = ByteArray(1024) 

    while((tmp=input.read(bytes))!=-1) { } 
}
2
  • What error (or errors) are you getting? Commented Apr 27, 2016 at 2:44
  • in " (a=b)" Error:(99, 9) Kotlin: Assignments are not expressions, and only expressions are allowed in this context Commented Apr 27, 2016 at 3:01

6 Answers 6

34

As @AndroidEx correctly stated, assignments are not expressions in Kotlin, unlike Java. The reason is that expressions with side effects are generally discouraged. See this discussion on a similar topic.

One solution is just to split the expression and move the assignment out of condition block:

a = b
if (a != c) { ... }

Another one is to use functions from stdlib like let, which executes the lambda with the receiver as parameter and returns the lambda result. apply and run have similar semantics.

if (b.let { a = it; it != c }) { ... }

if (run { a = b; b != c }) { ... }

Thanks to inlining, this will be as efficient as plain code taken from the lambda.


Your example with InputStream would look like

while (input.read(bytes).let { tmp = it; it != -1 }) { ... }

Also, consider readBytes function for reading a ByteArray from an InputStream.

Sign up to request clarification or add additional context in comments.

Comments

19

Java: (a = b) != c

Kotlin: b.also { a = it } != c


Unlike the accepted answer, I recommend using Kotlin's also function, instead of let:

while (input.read(bytes).also { tmp = it } != -1) { ...

Because T.also returns T (it) itself and then you can compare it with -1. This is more similar to Java's assignment as an expression.


See "Return this vs. other type" section on this useful blog for details.

1 Comment

Idea's automatic java to kotlin conversion does this too
12

Assignments are not expressions in Kotlin, thus you'll need to do it outside:

var a: Int? = 1
var b: Int? = 2
var c: Int? = 1

a = b
if (a != c)
    print(true)

For your other example with InputStream you could do:

fun readFile(path: String) {
    val input: InputStream = FileInputStream(path)
    input.reader().forEachLine {
        print(it)
    }
}

3 Comments

im try to use i/o stream, so i have to put a=b in if() or while(), how should i do
sorry, here is my original code fun readFile(path: String): Unit { var input: InputStream = FileInputStream(path) var string: String = "" var tmp: Int = -1 var bytes: ByteArray = ByteArray(1024) while((tmp=input.read(bytes))!=-1){ } }
Note: reader and forEachLine are not quite suitable for all the cases of an arbitrary byte stream, at least not with default (thus undefined) encoding which might not be single byte one and can fail at decoding the bytes. InputStream::readBytes is better for that.
12

As pretty much everyone here has pointed out, assignments are not expressions in Kotlin. However, we can coerce the assignment into an expression using a function literal:

val reader = Files.newBufferedReader(path)
var line: String? = null
while ({ line = reader.readLine(); line }() != null) {
    println(line);
}

Comments

0

I think this may help you:

 input.buffered(1024).reader().forEachLine {
            fos.bufferedWriter().write(it)
        }

Comments

0

the simple way in kotlin is

if (kotlin.run{ a=b; a != c}){ ... }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.