如何检查参数是否为lambda

如何检查参数是否为lambda,lambda,kotlin,Lambda,Kotlin,我正在处理MyCustomType的实例集合,如下所示: fun runAll(vararg commands: MyCustomType){ commands.forEach { it.myMethod() } } 除了MyCustomType的实例之外,我还想传递和处理()->Unit类型的lambda,类似这样: fun runAll(vararg commands: Any){ for(command in commands){ if (command

我正在处理
MyCustomType
的实例集合,如下所示:

fun runAll(vararg commands: MyCustomType){
    commands.forEach { it.myMethod() }
}
除了
MyCustomType
的实例之外,我还想传递和处理
()->Unit
类型的lambda,类似这样:

fun runAll(vararg commands: Any){
    for(command in commands){
        if (command is MyCustomType){
            command.myMethod()
        } else
        if(command is () -> Unit){
            command.invoke()
        }
    }
}
如果(命令为()->Unit){未编译,则行
不会显示以下消息:
无法检查已擦除类型的实例:()->Unit

有没有一种方法可以检查对象在运行时是否为
()->单元


我看到了。我认为这与此无关:我的代码不使用泛型。

Kotlin将把你的lambda编译成
Function0
的一个实例。如果你知道这一点,你可以使用
when
块来比较和智能转换:

fun runAll(vararg commands: Any) {
    commands.forEach {
        when(it) {
            is Function0<*> -> it.invoke()
            is MyCustomType -> it.myMethod()
        }
    }
}
fun runAll(vararg命令:任意){
forEach命令{
什么时候{
是Function0->it.invoke()
是MyCustomType->it.myMethod()
}
}
}
然后称之为:

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

警告:这种方法的缺点是,使用类型擦除时,您不知道是得到
Function0
还是
Function0
,因为运行时无法使用该类型来进行确定。这意味着有人可能会给您返回某个内容的lambda,而您将忽略结果lt.

您的
MyCustomType
本身不是
函数0
有什么原因吗? 如果是这样的话,您可以只使用
vararg命令:()->Unit
,然后您就可以调用
command()
,而不管传递的是什么(这与调用
command.invoke()
)是一样的。即使现在使用当前代码,您也可以这样做:

runAll
的签名更改为:

fun runAll(vararg commands: () -> Unit) { ...
然后使用以下命令调用它:

runAll(MyCustomType()::myMethod, { println("self-built-function") } /*, ... */)
或者同样的代码在使用自己的val时有点不同:

val customObj = MyCustomType()
runAll({ customObj.myMethod() }, { println("self-built-function") })
此外,如果您要求所有命令都有特定的返回值,您仍然可以这样做,例如,如果所有命令都必须返回
字符串,则只需使用
vararg命令:()->String

在这方面使用
Any
可能会导致将来的麻烦。如果您缩小类型范围,您至少可以确保您的命令总是以相同的方式运行。此外,您还可以通过这种方式获得最佳的代码完成支持。使用
Any
可以传递任何内容,但它不会运行所有内容

如果只想检查参数是否为lambda,还可以使用以下命令:

someObj is Function<*>
someObj是函数
但是,如果不将其强制转换为特定的函数类型,即:
Function0
Function1
,则不能调用
invoke

关于
函数0
等,托德已经回答了这个问题。但正如他在警告中所提到的:这有一个缺点。我只能建议尽可能省略
任何

可能的复制工作非常完美!Ty!是有意义的。肯定会这样做的。