如何将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正确指出的,与Java不同,赋值不是Kotlin中的表达式。 原因是有副作用的表情通常是不鼓励的。 请参阅有关类似主题的讨论。

一个解决方案就是拆分表达式,并将任务移出条件块:

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

另一个是使用stdlib中的函数,比如let ,它以接收器作为参数执行lambda表达式并返回lambda结果。 applyrun有类似的语义。

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

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

由于内联 ,这将与从lambda获取的普通代码一样高效。


你用InputStream例子看起来像

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

另外,考虑readBytes函数从InputStream读取一个ByteArray

作业不是 Kotlin中的表达式 ,因此您需要在外部完成:

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

这里几乎所有人都指出,任务不是Kotlin中的表达。 但是,我们可以使用函数文字强制赋值给一个表达式:

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