Kotin如何在Lambda中包含时指定返回标签

时间:2016-09-20 00:28:48

标签: java lambda kotlin

为游戏制作EntityContainer(NPC,玩家,对象等列表的容器)时遇到问题。当覆盖invoke操作符时,如果我的代码被包装在父lambda中,我就无法添加return语句。

import java.util.*

fun main(args: Array<String>) {
    val container = Container<String>()
    container.addList(listOf("h", "e", "l", "l", "o"))
    container.addList(listOf(" "))
    container.addList(listOf("w", "o", "r", "l", "d", "!"))

    Emptylambda {
        container[String(), Any(), Any()].forEach {
            val myCondition = true
            if (myCondition) return@forEach

            print(it)
        }
    }

    println("\n\n")

    Emptylambda {
        container[String(), Any(), Any()] {
            val myCondition = true
            if (myCondition) return //Does not compile

            print(it)
        }
    }

}


class Container<E> {

    private val lists = ArrayList<List<E>>(10)

    fun addList(list: List<E>) = lists.add(list)

    fun forEach(action: (E) -> Unit): Unit {
        lists.forEach {
            it.forEach {
                action(it)
            }
        }
    }

    operator fun invoke(action: (E) -> Unit) = this.forEach { action(it) }

    operator fun get(vararg ignored: Any): Container<E> { return this }
}

object Emptylambda {
    operator fun invoke(action: () -> Unit) {
        action()
    }
}

这是错误:

Error:(43, 21) Kotlin: 'return' is not allowed here

这是我写的一些小样本,可以轻松地重现这个问题。一个真实世界的例子如下。

GameScreen { 
     entities[EntityType.PLAYER, EntityType.NPC] {
           val entity = it
           if (!entity.isReady()) return //Cant use return here
           //Draw onto screen
     }
}

1 个答案:

答案 0 :(得分:2)

如果你想从内部lambda返回,你可以使用return at label

 Emptylambda outer@ {
     container[String(), Any(), Any()] inner@ {  // <--- add label here
        val myCondition = true
        if (myCondition) return@inner            // <--- exits from lambda 

        print(it)
    }
}

但你不能一直回到标签outer