如何将Java分配expression式转换为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中的expression式。 原因是有副作用的表情通常是不鼓励的。 请参阅有关类似主题的讨论。
一个解决方案就是拆分expression式,并将任务移出条件块:
a = b if (a != c) { ... }
另一个是使用stdlib中的函数,比如let
,它以接收器作为参数执行lambdaexpression式并返回lambda结果。 apply
和run
有类似的语义。
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中的expression式 ,因此您需要在外部完成:
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中的expression。 但是,我们可以使用函数文字强制赋值给一个expression式:
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) }