Как преобразовать выражение назначения Java в Kotlin

Что-то в java как

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

теперь он должен быть преобразован в kotlin как

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

но это неправильно.

Вот ошибка, которую я получаю:

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

На самом деле приведенный выше код является лишь примером для выяснения проблемы. Вот мой оригинальный код:

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

Как правильно указано @AndroidEx, присваивания не являются выражениями в Kotlin, в отличие от Java. Причина в том, что выражения с побочными эффектами обычно обескуражены. См. Обсуждение по аналогичной теме.

Одним из решений является просто разделить выражение и переместить назначение из блока условий:

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

Другим является использование функций из stdlib как let , который выполняет лямбда с приемником в качестве параметра и возвращает результат лямбда. apply и run аналогичные семантики.

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

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

Благодаря встраиванию это будет так же эффективно, как простой код, взятый из лямбда.


Ваш пример с InputStream будет выглядеть так:

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

Кроме того, рассмотрим функцию readBytes для чтения ByteArray из InputStream .

Задания не являются выражениями в Котлине, поэтому вам нужно сделать это за пределами:

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

Для вашего другого примера с InputStream вы можете сделать:

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

Как почти все здесь отметили, присвоения не являются выражениями в Котлине. Однако мы можем принудить присваивание к выражению, используя литерал функции:

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

Я думаю, это может помочь вам:

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