复杂的 MutableMap 类型
Complex MutableMap type
我有点糊涂了。
所以,我有一个类型为
的 mutableMap
val converters = mutableMapOf<String, Pair<KFunction<ElemBase>, x>>()
哪里搞不懂x
我需要根据构造函数和方法向此映射添加几对,例如:
converters["Camera"] = ::Camera to Structure::convertCamera
其中第一个字段是对扩展 ElemBase
的构造函数的引用,例如:
Camera : ElemBase
第二个是 Structure
class 上的一个方法,它引用了一个可为 null 的 ElemBase
class:
fun convertCamera (dest: KMutableProperty0<Camera?>)
当x
KFunction<*>
有效,但我需要更具体的东西,其中定义了 Receiver
和参数。
我尝试了几次,例如
KFunction<Structure.(KProperty1<Structure, ElemBase>) -> Unit>
或
KFunction<(KMutableProperty0<ElemBase>) -> Unit>
或
KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>
每当我尝试向 converters
添加任何内容时,我总是会出错
Error:(276, 9) Kotlin: Type inference failed: Cannot infer type parameter V in operator inline fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit
None of the following substitutions
receiver: MutableMap<String, Pair<Int, KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>>> arguments: (String,Pair<Int, KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>>)
receiver: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
can be applied to
receiver: MutableMap<String, Pair<Int, KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
但到目前为止还没有运气
有趣的是,如果我将 ::Camera to Structure::convertCamera
分配给一个变量,我会得到以下类型:
Pair<KFunction0<ElemBase>, KFunction2<Structure, @ParameterName KMutableProperty0<ElemBase>, Unit>>
但我没有 KFunction0
也没有 KFunction2
... 这到底是怎么回事?
编辑:找到 this
Edit2:如果我手动导入 KFunction0
和 KFunction2
,它似乎不再抱怨它们了。但是如果我点击它们,它无法解析..
我尝试手动导入 KFunction0
和 KFunction2
,复制我在将这对分配给 var
时看到的类型,看起来这是可行的:
val converters = mutableMapOf<String, Pair<KFunction0<Camera>, KFunction2<Structure, KMutableProperty0<Camera>, Unit>>>()
但不是对应的ElemBase
版本:
val converters = mutableMapOf<String, Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>>()
Error:(277, 9) Kotlin: Type inference failed: Cannot infer type parameter V in operator inline fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit
None of the following substitutions
receiver: MutableMap<String, Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>> arguments: (String,Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>)
receiver: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
can be applied to
receiver: MutableMap<String, Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
虽然我仍然不明白 KFunction*
是怎么回事,但为什么它们似乎不存在,尽管一旦手动导入,编译器就会接受它们
以防设计有问题,我在这里移植了一些 c++ 代码,如果可能的话我想坚持原来的结构
Edit3:好的,我可能会更改设计,但出于好奇,我还是想知道发生了什么事
如果你在IntelliJ中写下如下代码:
val map = mutableMapOf("Camera" to (::Camera to Structure::convertCamera))
然后您可以对赋值调用 "specify type explicitly" 意图操作,或在变量上按 "Ctrl + Q" 以显示其推断的类型信息。
这将为您带来以下内容:
val map: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName(name = "dest") KMutableProperty0<Camera?>, Unit>>>
KFunction0
和 KFunction2
这里是 Kotlin 编译函数类型的一些 类(分别具有 0 和 2 个参数)。来自 Kotlin in Action 书:
The Kotlin standard library defines a series of interfaces, corresponding to different numbers of function arguments: Function0<R>
(this function takes no arguments), Function1<P1, R>
(this function takes one argument), and so on. Each interface defines a single invoke method, and calling it will execute the function.
您可以将它们替换为函数类型,并删除一些不必要的特定信息,如下所示:
val map: MutableMap<String, Pair<() -> Camera, (Structure, KMutableProperty0<Camera?>) -> Unit>>
因为你希望 ElemBase
是类型而不是具体的 Camera
类型,你可以这样做:
val map3: MutableMap<String, Pair<() -> ElemBase, (Structure, KMutableProperty0<Camera?>) -> Unit>>
但是,您不能将 KMutableProperty0<Camera>
更改为 KMutableProperty0<ElemBase>
,因为此类型是 invariant,因此这会破坏示例中的分配。就像 MutableList<T>
一样,它既接受也产生它的泛型,因此它不能在它的泛型参数中接受一个子类型或超类型,而不是需要的。
我有点糊涂了。
所以,我有一个类型为
的 mutableMapval converters = mutableMapOf<String, Pair<KFunction<ElemBase>, x>>()
哪里搞不懂x
我需要根据构造函数和方法向此映射添加几对,例如:
converters["Camera"] = ::Camera to Structure::convertCamera
其中第一个字段是对扩展 ElemBase
的构造函数的引用,例如:
Camera : ElemBase
第二个是 Structure
class 上的一个方法,它引用了一个可为 null 的 ElemBase
class:
fun convertCamera (dest: KMutableProperty0<Camera?>)
当x
KFunction<*>
有效,但我需要更具体的东西,其中定义了 Receiver
和参数。
我尝试了几次,例如
KFunction<Structure.(KProperty1<Structure, ElemBase>) -> Unit>
或
KFunction<(KMutableProperty0<ElemBase>) -> Unit>
或
KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>
每当我尝试向 converters
Error:(276, 9) Kotlin: Type inference failed: Cannot infer type parameter V in operator inline fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit
None of the following substitutions
receiver: MutableMap<String, Pair<Int, KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>>> arguments: (String,Pair<Int, KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>>)
receiver: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
can be applied to
receiver: MutableMap<String, Pair<Int, KFunction<Structure.(KMutableProperty0<ElemBase?>) -> Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
但到目前为止还没有运气
有趣的是,如果我将 ::Camera to Structure::convertCamera
分配给一个变量,我会得到以下类型:
Pair<KFunction0<ElemBase>, KFunction2<Structure, @ParameterName KMutableProperty0<ElemBase>, Unit>>
但我没有 KFunction0
也没有 KFunction2
... 这到底是怎么回事?
编辑:找到 this
Edit2:如果我手动导入 KFunction0
和 KFunction2
,它似乎不再抱怨它们了。但是如果我点击它们,它无法解析..
我尝试手动导入 KFunction0
和 KFunction2
,复制我在将这对分配给 var
时看到的类型,看起来这是可行的:
val converters = mutableMapOf<String, Pair<KFunction0<Camera>, KFunction2<Structure, KMutableProperty0<Camera>, Unit>>>()
但不是对应的ElemBase
版本:
val converters = mutableMapOf<String, Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>>()
Error:(277, 9) Kotlin: Type inference failed: Cannot infer type parameter V in operator inline fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit
None of the following substitutions
receiver: MutableMap<String, Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>> arguments: (String,Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>)
receiver: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
can be applied to
receiver: MutableMap<String, Pair<KFunction0<ElemBase>, KFunction2<Structure, KMutableProperty0<ElemBase>, Unit>>> arguments: (String,Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName KMutableProperty0<Camera>, Unit>>)
虽然我仍然不明白 KFunction*
是怎么回事,但为什么它们似乎不存在,尽管一旦手动导入,编译器就会接受它们
以防设计有问题,我在这里移植了一些 c++ 代码,如果可能的话我想坚持原来的结构
Edit3:好的,我可能会更改设计,但出于好奇,我还是想知道发生了什么事
如果你在IntelliJ中写下如下代码:
val map = mutableMapOf("Camera" to (::Camera to Structure::convertCamera))
然后您可以对赋值调用 "specify type explicitly" 意图操作,或在变量上按 "Ctrl + Q" 以显示其推断的类型信息。
这将为您带来以下内容:
val map: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName(name = "dest") KMutableProperty0<Camera?>, Unit>>>
KFunction0
和 KFunction2
这里是 Kotlin 编译函数类型的一些 类(分别具有 0 和 2 个参数)。来自 Kotlin in Action 书:
The Kotlin standard library defines a series of interfaces, corresponding to different numbers of function arguments:
Function0<R>
(this function takes no arguments),Function1<P1, R>
(this function takes one argument), and so on. Each interface defines a single invoke method, and calling it will execute the function.
您可以将它们替换为函数类型,并删除一些不必要的特定信息,如下所示:
val map: MutableMap<String, Pair<() -> Camera, (Structure, KMutableProperty0<Camera?>) -> Unit>>
因为你希望 ElemBase
是类型而不是具体的 Camera
类型,你可以这样做:
val map3: MutableMap<String, Pair<() -> ElemBase, (Structure, KMutableProperty0<Camera?>) -> Unit>>
但是,您不能将 KMutableProperty0<Camera>
更改为 KMutableProperty0<ElemBase>
,因为此类型是 invariant,因此这会破坏示例中的分配。就像 MutableList<T>
一样,它既接受也产生它的泛型,因此它不能在它的泛型参数中接受一个子类型或超类型,而不是需要的。