如何检查参数是否为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!是有意义的。肯定会这样做的。