如何在地图中存储一个函数(或lambda)然后执行它?

时间:2019-01-03 23:27:47

标签: android kotlin

我想有一个MutableMap,它在某种逻辑上映射类。它主要用于对来自后端的某些对象做出反应。例如。

class ViewUpdater(val view: RecordingActivity) {
    val map: MutableMap<KClassifier, Function<*>> = mutableMapOf()

    init {
        map[Entity1::class] = { m: Entity ->
            view.entity1.text = (m as Entity1).value1.toString()
        }
        map[Entity2::class] = { m: Entity ->
            view.entity2.text = (m as Entity2).value2.toString()
        }
}

但是我不知道类型Function<*>是否正确。之后,很明显,当我手头有一个特定的对象时,我想执行我的函数/ lambdas:例如

 .subscribe(
            { it: Entity ->
                   map[it::class] // and what next here... ?
                }
            }

谢谢。

2 个答案:

答案 0 :(得分:1)

您可以使用:

MutableMap < KClass<Entity>, (Entity) -> Unit >  = mutableMapOf()

或:

MutableMap < KClass<Entity>, Function1<Entity, Unit> >  = mutableMapOf()

代替使用地图,您可以使用此方法

fun <T: Entity> setViewText(en: T) =
             when(en){
               is Entity1 -> view.entity1.text = en.value1.toString()
               is Entity2 -> view.entity2.text = en.value2.toString()
               else -> throw Exception("Invalid Entity")
             }

您没有获得订阅签名,但我猜测可以这样运行(如果subscribe的lambda参数为(Entity) -> Unit并具有实体接收者):

.subscribe{ map[this::class] } // if subscribe has Entity receiver

如果订阅还没有实体接收者:

.subscribe{ map[it::class]?.invoke(it) }

答案 1 :(得分:0)

您正在寻找invoke()运算符。就您而言,您可以执行以下操作:

.subscribe { map[it::class]?.invoke(it) }

请注意,如果您没有为特定的Entity子类映射函数,则此方法可能返回null。另外,如果您的意图是将when的特定子类映射到Entity,则我可能建议使用String语句作为扩展功能以提高可读性。例如:

fun Entity.toSpecialString() : String = when(this) {
    is Entity1 -> value1.toString()
    is Entity2 -> value2.toString()
    else -> "unspecified"
}

然后您可以做:

.subscribe { it.toSpecialString() }