首页 > 解决方案 > 如何检查参数是否为 lambda

问题描述

我正在处理以下实例的集合MyCustomType

fun runAll(vararg commands: MyCustomType){
    commands.forEach { it.myMethod() }
}

除了 的实例之外MyCustomType,我还想传递和处理 type 的 lambda () -> Unit,如下所示:

fun runAll(vararg commands: Any){
    for(command in commands){
        if (command is MyCustomType){
            command.myMethod()
        } else
        if(command is () -> Unit){
            command.invoke()
        }
    }
}

该行if(command is () -> Unit){未编译并显示以下消息:Cannot check for instance of erased type: () -> Unit.

有没有办法检查对象是否() -> Unit在运行时?

我看到了另一个建议使用通配符的答案。我认为这无关紧要:我的代码不使用泛型。

标签: lambdakotlin

解决方案


Kotlin 会将您的 lambda 编译为Function0. when如果你知道这一点,你可以很好地使用块来比较和智能转换:

fun runAll(vararg commands: Any) {
    commands.forEach {
        when(it) {
            is Function0<*> -> it.invoke()
            is MyCustomType -> it.myMethod()
        }
    }
}

然后调用它:

fun main(args: Array<String>) {
    runAll(
        MyCustomType(), 
        { println("Lambda!") }
    )
}

警告:这种方法的缺点是使用类型擦除,您不知道您得到的是 aFunction0<Unit>还是 a Function0<Int>,因为该类型在运行时不可用,您无法做出决定。这意味着有人可以给你一个返回某些东西的 lambda,而你会忽略结果。


推荐阅读