我可以在Runnable中“提早返回”吗?

时间:2018-11-08 06:54:50

标签: kotlin

Runnable块中,我想做一些“防护块”,如下所示:

var condition: String? = null
Runnable {
    if (condition == null) return
    // do something
}

但是编译器说“这里不允许返回”?

2 个答案:

答案 0 :(得分:1)

有两种方法可以使这项工作:

如评论中所述,您可以使用here中讨论的“合格回报”。这也是IntelliJ(我猜也是AndroidStudio)建议: enter image description here

或者,您可以将Runnable定义为一个匿名类,使您可以使用普通的return语句:

 object: Runnable {
     override fun run() {
         if (condition == null) return
         // do something
     }
 }

IntelliJ现在建议将此object转换为lambda,这将导致完全相同的结果与合格的return

Runnable {
    if (condition == null) return@Runnable
    // do something
}

PS:无需感到愚蠢!我想您会以正确的措词轻松找到它。很高兴知道这里的Runnable {}。它基本上是一个基于SAM conversion的lambda(适用于具有单个抽象方法的Java类型)

答案 1 :(得分:1)

要扩展s1m0nw1的答案,使用return@Runnable是正确的。

在这种情况下,

@Runnable定义了您返回的内容。它也适用于循环,也适用于方法。这是一个带有循环的示例:

fun test(){
    one@for(i in 0..100){
        two@for(j in 0..i){
            if(j == 20){
                break;//this breaks two
            }
        }
    }
}

此示例在j == 20时中断第二个示例。如果要在j为20时中断外循环(这可能不是最好的示例,但您仍然可以理解),则可以使用{{ 1}}。对于循环,仅当您显式声明标签时才有效。

在某些情况下,您基本上必须指定要中断/返回/继续的内容(取决于您使用的内容)。从常规方法返回或中断单个循环不需要显式标记,但是如果您使用lambda或希望中断外部循环,则可以将目标锁定为使用break@one

在我添加的示例中,如果要返回而不是中断,则可以使用[return/break/continue]@LabelMethodClassOrInterfaceName。但是,这一点没有意义,因为在这种情况下return@test暗示了方法。

使用这种类型的lambda,您不得不使用returnreturn@InterfaceName被替换为您正在使用的任何接口(在本例中为Runnable)。

或者您当然可以让IntelliJ为您自动完成它。