Functional programming 科特林功能战略模式不';不编译
我试图在一个映射中放置几个函数。这样做的想法是:Functional programming 科特林功能战略模式不';不编译,functional-programming,kotlin,Functional Programming,Kotlin,我试图在一个映射中放置几个函数。这样做的想法是:Map 代码如下: class UserIdQueriesHandler { val strategy: Map<String, KFunction2<@ParameterName(name = "id") String, @ParameterName(name = "options") Array<Options>, Answer>> = mapOf( // the compiler
Map
代码如下:
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
编译器输出:
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>>
类型推断失败。预期类型不匹配:
必修的:
地图
发现:
地图
策略的类型表示,您放入其中的函数可以接受任何数组
作为第二个参数,而债务
和当前产品
则不能
最简单的解决方法是将其参数类型更改为Array
(或List
;它们可能不需要对其进行变异!),如果传递错误的选项或忽略它们,则在运行时失败
文档中的部分也是相关的。策略的类型表示,您放入其中的函数可以接受任何
数组
作为第二个参数,而债务
和当前产品
则不能
最简单的解决方法是将其参数类型更改为Array
(或List
;它们可能不需要对其进行变异!),如果传递错误的选项或忽略它们,则在运行时失败
文档中的节也是相关的。由于数组既可以读也可以写,因此其类型参数为。这使得您无法将
数组
分配给类型为数组
的变量。前者不是后者的子类型,因为它允许您在数组中放置选项
,而不是债务选项
,从而导致将此数组引用为数组
的代码出现问题
如果可以的话,一个解决方案是让函数接受数组
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 = ...
由于
数组既可以读取也可以写入,因此其类型参数为。这使得您无法将数组
分配给类型为数组
的变量。前者不是后者的子类型,因为它允许您在数组中放置选项
,而不是债务选项
,从而导致将此数组引用为数组
的代码出现问题
如果可以的话,一个解决方案是让函数接受数组
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 = ...
Array
不协变有点麻烦(这就是为什么我在回答中没有提到它):因为函数在它们的参数中是逆变的,只有逆变类型会进行类型检查,但它在语义上没有意义。我有点如下,但在语义上有什么意义?我的意思是:1。如果将数组
的所有用法替换为逆变类型(例如(a)->单位
,那么策略中的(选项)->单位
和债务中的(债务选项)->单位
),代码将编译(可能具有更明确的类型注释)。2.然后您就有了有趣的债务(id:String,options:(DebtOptions)->Unit):UserDebt=…
。3.但是你会如何使用第二个参数呢?Array
不协变有点像是在转移注意力(这就是为什么我在回答中没有提到它):因为函数在其参数中是逆变的,只有逆变类型会进行类型检查,但在语义上没有意义。我有点如下所述,但是什么在语义上没有意义呢?我的意思是:1。如果将数组
的所有用法替换为逆变类型(例如(a)->单位
,那么策略中的(选项)->单位
和债务中的(债务选项)->单位
),代码将编译(可能具有更明确的类型注释)。2.然后您就有了有趣的债务(id:String,options:(DebtOptions)->Unit):UserDebt=…
。3.那么,您将如何使用第二个参数呢?
val strategy: Map<String, (String, Array<Options>) -> Answer> = ...