'返回'不会跳出Kotlin中的forEach

时间:2018-01-02 07:16:41

标签: android kotlin

我有这个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'不表示循环

3 个答案:

答案 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中是一个非常引人注目的功能,无论如何你迟早都要处理,所以你不妨使用它来使你的代码更具可读性。