在Java中,有时我编写如下代码:
String obj = null;
while ((obj = getObject()) != null) {
// do smth with obj
}
在Kotlin中显示了编译时错误:
赋值不是表达式,在这种情况下只能使用表达式
在Kotlin中最好的等同物是什么?
答案 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
。如果要保留最后一个值或将这些值汇总为其他值,则可以用.forEach
或reduce
(或其他任何合适的方法;-)代替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) {
// ...
}