0

我在这里有点困惑。

所以,我有一个 mutableMap 类型

val converters = mutableMapOf<String, Pair<KFunction<ElemBase>, x>>()

我想不通的地方x

我需要根据构造函数和方法向此映射添加几对,例如:

converters["Camera"] = ::Camera to Structure::convertCamera

其中第一个字段是对扩展构造函数的引用ElemBase,例如:

Camera : ElemBase

第二个是Structure引用可空ElemBase类的类上的方法:

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......这到底是什么?

编辑:找到这个

Edit2:如果我手动导入KFunction0KFunction2它似乎不再抱怨它们了。但如果我点击它们,它无法解决..

我尝试手动导入KFunction0KFunction2,复制我在将这对分配给 a 时看到的类型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:好的,我可能会改变设计,但出于好奇,我还是想知道发生了什么

4

1 回答 1

2

如果你在 IntelliJ 中写下以下代码:

val map = mutableMapOf("Camera" to (::Camera to Structure::convertCamera))

然后,您可以对赋值调用“显式指定类型”意图操作,或在变量上按“Ctrl + Q”以显示其推断的类型信息。

这将为您提供以下信息:

val map: MutableMap<String, Pair<KFunction0<Camera>, KFunction2<Structure, @ParameterName(name = "dest") KMutableProperty0<Camera?>, Unit>>>

KFunction0KFunction2以下是 Kotlin 将函数类型编译成的一些类(分别具有 0 和 2 个参数的类)。来自Kotlin in Action一书:

Kotlin 标准库定义了一系列接口,对应不同数量的函数参数:(Function0<R>这个函数没有参数),Function1<P1, R>(这个函数有一个参数),等等。每个接口定义一个调用方法,调用它会执行函数。

您可以将这些替换为函数类型,并删除一些不必要的特定信息,如下所示:

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>,它既接受又产生其泛型类型,因此它不能在其泛型参数中接受子类型或超类型,而不是所需的。

于 2018-02-14T21:06:23.723 回答