Ссылка на недвижимость и лямбда для получения / установки - PullRequest
0 голосов
/ 06 апреля 2020

Мне нужно получить и установить свойство другого класса из метода, и поэтому мне нужно передать либо ссылку на свойство lambdas для метода получения и установки:

  1. Передача ссылка на свойство

    otherInstance::property

  2. Переход в лямбду для геттера и один для сеттера:

    {otherInstance.property} // getter

    {value -> otherInstance.property = value} // setter

Мне нравится первый, потому что для меня код легче читать и короче, но мой сигнал тревоги звучит, когда я читаю об этом на официальная документация , из-за термина "отражение". Насколько мне известно из Java, рефлексия, как правило, не очень хорошая вещь. Это также верно с Kotlin? Это действительно в этом случае? Является ли один из обоих способов (ссылка на свойство или лямбда-выражение) более производительным или более безопасным?

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

Используя KMutableProperty0, вы технически выставляете объект, который можно использовать для отражения. Если вы хотите быть строгим во избежании отражения, вы можете использовать отдельные ссылки на функции для метода получения и установки. Обратите внимание, что нет необходимости передавать лямбду как ссылку на функцию в функцию более высокого порядка. Компилятор может интерпретировать ссылки на свойства как функции, если эффективная сигнатура совпадает. Это, к сожалению, означало бы необходимость дважды передавать ссылку на свойство. К сожалению, сеттер должен быть извлечен через то, что технически является отражением в этом случае:

class Test (var x: Int)

fun foo(getter: () -> Int, setter: (Int) -> Unit) {
    //...
}

val test = Test(1)
foo(test::x, test::x.setter)

// Zero reflection call:
foo(test::x) { test.x = it }

В какой-то момент вы должны задаться вопросом, насколько сильно вы хотите избежать отражения, потому что приведенный выше код выглядит для меня очень грязно , Если ваш класс использует ссылку KMutableProperty0, его гораздо проще использовать. Пока ваша принимающая функция не использует ссылку для внутреннего анализа кода, а только вызывает get() или set(), вы на самом деле не используете рефлексию в способах, которые рекомендуется избегать.

fun foo(property: KMutableProperty0<Int>) {
    //...
}

val test = Test(1)
foo(test::x)
1 голос
/ 06 апреля 2020

Документация о Ссылки и отражения членов ,

Если вы ссылаетесь на Ссылки на свойства , которые не используют само отражение,

Отражение упоминается только в другом разделе Получение ссылок на члены из ссылки на класс

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

Kotlin имеет собственную библиотеку отражений (kotlin -reflect.jar должен быть включен в ваша сборка). При нацеливании на JVM вы также можете использовать Java средства отражения. Обратите внимание, что отражение Kotlin еще не совсем полно - в частности, вы не можете использовать его для проверки встроенных классов, таких как String.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...