Что делает ключевое слово "по" в Котлине?

При разработке для Android я иногда сталкиваюсь с чем-то вроде этого:

var someModel: someViewModel by notNullAndObservable { vm ->
  ...
}

Я не понимаю, каково значение ключевого слова by.

Ответы

Ответ 1

В ссылке Kotlin вы найдете два варианта использования by, первый из которых - делегированные свойства которое вы используете выше:

Существуют определенные общие виды свойств, которые, хотя мы можем реализовать их вручную каждый раз, когда они нам понадобятся, было бы очень приятно реализовать раз и навсегда и поместить в библиотеку. Примеры включают ленивые свойства: значение вычисляется только при первом доступе, наблюдаемые свойства: слушатели получают уведомление об изменениях в этом свойстве, сохраняя свойства на карте, а не в отдельном поле.

Здесь вы делегируете getter/setter другому классу, который выполняет эту работу, и может содержать общий код. В качестве другого примера некоторые инжекторы зависимостей для Kotlin поддерживают эту модель, делегируя получателю получение значения из реестра экземпляров, управляемых механизмом впрыска зависимостей.

И Передача интерфейса/класса - это другое использование:

Схема делегирования оказалась хорошей альтернативой наследованию реализации, и Kotlin поддерживает ее, требуя нулевой код шаблона. Класс Derived может наследовать от интерфейса Base и делегировать все его общедоступные методы указанному объекту

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

В качестве примера можно привести Klutter Readonly/Immutable collections, где они просто делегируют конкретный интерфейс коллекции другому классу, а затем переопределяют все, что должно быть другим в только для чтения. Сохранение большой работы, не требующей вручную делегировать все другие методы.

Оба из них охватываются ссылкой ссылка на язык Kotlin, начните там для базовых тем языка.

Ответ 2

Проще говоря, вы можете понять по ключевому слову, как указано в.

С точки зрения потребителя свойства val - это то, что имеет getter (get), а var - то, что имеет getter и setter (get, set). Для каждого свойства var есть поставщик по умолчанию методов get и set, который нам не нужно явно указывать.

Но, используя ключевое слово by, вы утверждаете, что этот метод получения/получения и установки предоставляется в другом месте (т.е. он был делегирован), он предоставляет посредством функции, которая следует после.

Таким образом, вместо использования этих встроенных методов get и set, вы делегируете это задание какой-то явной функции.

Один очень распространенный пример - от lazy для свойств отложенной загрузки. Кроме того, если вы используете библиотеку внедрения зависимостей, такую как Koin, вы увидите много свойств, определенных следующим образом:

var myRepository: MyRepository by inject()  //inject is a function from Koin

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

class MyClass: SomeInterface by SomeImplementation, SomeOtherInterface

Этот код говорит: Я класс MyClass и я предлагаю функции интерфейса SomeInterface, которые предоставляет SomeImplementation. Я сам реализую SomeOtherInterface (это неявно, так что нет)