我正在尝试将几个函数放在地图中。我的想法是:Map<String, [function]>
。
代码如下:
class UserIdQueriesHandler {
val strategy: Map<String, KFunction2<@ParameterName(name = "id") String, @ParameterName(name = "options") Array<Options>, Answer>> =
mapOf( // the compiler complains here
"d" to ::debt,
"p" to ::currentProduct
)
fun debt(id: String, options: Array<DebtOptions>): UserDebt = UserDebt(isPresent = true, amount = 0.0)
fun currentProduct(id: String, options: Array<CurrentProductOptions>): UserProducts = UserProducts(products = emptyList())
}
enum class DebtOptions : Options { BOOL, AMOUNT }
enum class CurrentProductOptions : Options { ALL, PRINT, DIGITAL, ENG, HEB, TM }
data class UserDebt(val isPresent: Boolean, val amount: Double) : Answer
data class UserProducts(val products: List<Int>): Answer
Answer
和Options
是简单的kotlin接口:
interface Answer
interface Options
编译器输出:
Type inference failed. Expected type mismatch:
required:
Map<String, KFunction2<@ParameterName String, @ParameterName Array<Options>, Answer>>
found:
Map<String, KFunction2<@ParameterName String, {[@kotlin.ParameterName] Array & [@kotlin.ParameterName] Array }, Answer>>
答案 0 :(得分:1)
strategy
的类型表示您放入其中的函数可以接受任何Array<Options>
作为第二个参数,debt
和currentProduct
可以&#t}}。
最简单的解决方法是将其参数类型更改为Array<Options>
(或List<Options>
;它们可能不需要改变它!)并在运行时失败,如果传递了错误的选项或忽略它们。
Variance部分也是相关的。
答案 1 :(得分:1)
由于Array
可以同时读写,因此其类型参数为invariant。这使得您无法将Array<DebtOptions>
分配给类型为Array<Options>
的变量。前者不是后者的子类型,因为它允许您将其他元素放在数组中Options
,而不是DebtOptions
,从而导致代码中出现问题此数组为Array<DebtOptions>
。
如果可以,解决方案是让您的函数接受Array<Options>
。
val strategy: Map<String, KFunction2<String, Array<Options>, Answer>> =
mapOf(
"d" to ::debt,
"p" to ::currentProduct
)
fun debt(id: String, options: Array<Options>): UserDebt = ...
fun currentProduct(id: String, options: Array<Options>): UserProducts = ...
您可以将此与使用更好的功能类型而不是KFunction2
:
val strategy: Map<String, (String, Array<Options>) -> Answer> = ...