Kotlin:如何处理任何输入types和给定输出types的函数

我有签名(ShellInput) -> ShellOutput 。 参考这些被存储在地图中:

 mutableMapOf ShellOutput>("trim" to ::trim) 

然后从这张地图中提取这些地图,并通过reflection进行调用。 现在需要有输入types可以改变的function,所以我试着:

 mutableMapOf ShellOutput>("trim" to ::trim) 

但是这不起作用。 我该如何处理?

实际上,把::trim作为一个值放入mutableMapOf ShellOutput>会破坏types安全性:当你从地图中取出一个值后,它被输入为(Any) -> ShellOutput ,让你传递Any作为参数的函数。 types系统不允许这样做。

作为解决方法,您可以使用星型投影typesFunction1<*, ShellOutput> ,这意味着参数types是未知的:

 mutableMapOf>("trim" to ::trim) 

当你从这张图中得到一个值时,你会看到函数接受的参数types是Nothing 。 这是完全可以预料的,types系统再次保留了types安全性:没有任何东西可以安全地传递给一个未知参数types的函数( Nothing是没有值的types)。

现在是时候通过使用未经检查的转换来向编译器显示更多关于types的信息了:

 @Suppress("UNCHECKED_CAST") val trim = functions["trim"] as Function1 

您可以将演员封装到一个扩展名,如下所示:

 @Suppress("UNCHECKED_CAST") fun  Map>.getWithParameter(key: String): Function1 = get(key) as Function1 // Usage: functions.getWithParameter("trim") 

或者,使用KFunction 。 它可以让你免受未经检查的强制转换,但从一开始就不太安全,因为它不控制参数的数量,你可以使用任何types的任意数量的参数来调用.call(...)这样的函数引用。