Данный

class X {
    fun f() {...}
    fun g() {...}
    ...
}

Я хотел бы вызвать f, g или другую функцию класса по имени, которое динамически известно во время выполнения. Это возможно с отражением котлина, например

val callback : KCallable<*>? = X::class.members.firstOrNull { it.name == predVar }
if (callback != null) {
    callback.call(obj, ...)

Единственная загвоздка здесь в том, что у моего мультиплатформенного приложения есть цели, отличные от JVM. Например, возможно ли отражение котлина в javascript? Конечно, JS - это язык с динамической типизацией, поэтому у меня вопрос, реализован ли он там уже.

В качестве альтернативы я могу иметь коллекцию или карту этих функций. Каким будет наиболее элегантный синтаксис определения списка функций и их динамического вызова? Например, учитывая несколько атрибутов типа перечисления, я могу создать кучу логических методов, подобных этому

var booleanDerivatives = hashMapOf<String, () -> Boolean>(
    "breaksAfterComma" to fun (): Boolean {
        return options[breaksComma] === Breaks.After
    }
    ,"breaksBeforeComma" to fun (): Boolean {
        return options[breaksComma] === Breaks.Before
    }
    ,"breaksAfterLogicalConjunction" to fun (): Boolean {
        return options[breaksAroundLogicalConjunctions] === Breaks.After 
            || options[breaksAroundLogicalConjunctions] === Breaks.BeforeAndAfter
    }
)

Однако, в отличие от отражения, мне, кажется, приходится использовать строковые литералы, потому что без отражения нет механизма, переводящего имя в строку. Или есть?

2
Tegiri Nenashi 28 Мар 2019 в 02:55

1 ответ

Лучший ответ

Согласно документам, вы не можете получить доступ к методам через отражение в Цель JS. Вам нужно будет поддерживать свою собственную коллекцию ссылок на функции, чтобы добиться того, что вы описываете как цели JVM, так и JS.

2
Paul Hicks 28 Мар 2019 в 00:19