我有这个Kotlin代码,为什么 return @ forEach 没有跳出 forEach ?它继续循环直到完成,删除reversed()不解决问题:
rendered_words.reversed().forEach { rw ->
if (rw.y - the_top > 0 && rw.y - the_top < height) {
new_top = rw.y
return@forEach
}
}
smoothScrollTo(Math.min(text_y - height, new_top))
我尝试用 break @ forEach 替换 return @ forEach ,但Kotlin编译器说:
错误:(785,25)标签'@forEach'不表示循环
答案 0 :(得分:7)
如果你想跳出forEach,你应该使用一个运行块:
run breaker@ {
rendered_words.reversed().forEach { rw ->
if (rw.y - the_top > 0 && rw.y - the_top < height) {
new_top = rw.y
return@breaker
}
}
}
答案 1 :(得分:4)
这种做法怎么样?
rendered_words.reversed().firstOrNull { rw -> rw.y - the_top > 0 && rw.y - the_top < height }
?.let { new_top = it }
if(new_top != null) {
smoothScrollTo(Math.min(text_y - height, new_top))
}
因为你似乎试图到达的地方是第一个符合你条件的项目,第一个/ firstOrNull比forEach更好
答案 2 :(得分:0)
我对此的回答是使用Kotlin令人惊叹的扩展机制,这意味着您可以随意添加方法:
/**
* Iterate a list.
* The consumer can break the iteration by returning
* Control.BREAK
* Returns <tt>true</tt> if no break occured
*
*/
enum class Control { BREAK, CONTINUE }
fun <T> List<T>.each(consumer : (T) -> Control) : Boolean {
for( t in this) {
when(consumer(t)) {
Control.BREAK -> return false
}
}
return true
}
现在你可以这样做:
list.each {
if(...) {
logger.debug { "break" }
return@each Control.BREAK
} else {
logger.debug { "continue" }
return@each Control.CONTINUE
}
}
我认为扩展方法在Kotlin中是一个非常引人注目的功能,无论如何你迟早都要处理,所以你不妨使用它来使你的代码更具可读性。