Kotlin与Java“分配和检查”等效吗?

时间:2019-01-31 08:10:17

标签: java kotlin

在Java中,有时我编写如下代码:

 String obj = null;
 while ((obj = getObject()) != null) {
    // do smth with obj
 }

在Kotlin中显示了编译时错误:

  

赋值不是表达式,在这种情况下只能使用表达式

在Kotlin中最好的等同物是什么?

5 个答案:

答案 0 :(得分:5)

我宁愿放弃幻想,而是以最传统的方式进行操作,这是最直观的方式。

 var obj = getObject();
 while (obj != null) {
    // do smth with obj
    obj = getObject();
 }

答案 1 :(得分:3)

最简单的ad-hock解决方案可能是

while(true) {
    val obj = getObj() ?: break
}

但是,特殊情况下,最好由专门的助手功能为IMO提供服务。例如,可以使用answer中的帮助程序readLines逐行读取文件,以解决类似的问题:

reader.forEachLine {
    println(it)
}

答案 2 :(得分:3)

如果您只想替换while ((x = y.someFunction()) != null),则可以改用以下内容:

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

generateSequence将一个一个地提取所有值,直到到达第一个null。如果要保留最后一个值或将这些值汇总为其他值,则可以用.forEachreduce(或其他任何合适的方法;-)代替fold

如果您需要检查其他内容,则可以添加诸如takeIf之类的内容,例如:

generateSequence { y.someFunction().takeIf { /* yourCondition... */ } }

基本上只是重复我也提到的here

答案 3 :(得分:2)

我已经修改过,并提出了一个简洁的常规辅助函数:

inline fun <T> (() -> T?).untilNull(action: (T) -> Unit) { 
    while (true) action(this() ?: break) 
}

可以这样称呼:

::getObject.untilNull { /* do something with "it" */ }

您当然可以不用此辅助功能,而只使用while

while(true){
    val result = getObject() ?: break
    // do something with "result"
}

另一种解决方案是创建一个内联lambda,然后立即调用它:

var result = null
while ({ result = getObject(); result }() != null){
    // do something with "result"
}

如果您先“保存” lambda,则可能可以对其进行优化:

var result = null
var assignment = { result = getObject(); result };
while (assignment() != null){
    // do something with "result"
}

答案 4 :(得分:0)

怎么样:

while (getObject().apply { obj = this } != null) {
    // ...
}