Содержание
Введение
- Эта серия статей не будет расположена в каком-либо определенном порядке, поэтому не стесняйтесь читать любые записи в блоге, которые вам нравятся. Если я найду что-то, о чем, на мой взгляд, можно написать статью в блоге, я напишу ее и размещу здесь.
Краткое содержание всего поста в блоге
- Итак, в
by viewModels {}
мы сначала создаем свойство делегата с помощью ключевого словаby
. Затем мы используем функцию расширенияviewModels
для делегирования нового метода getter нашему свойству делегата. Наконец,{}
позволяет определить лямбда-выражение для возврата значения, которое будет храниться в нашем свойстве.
О чем мы будем говорить
- В конечном итоге, цель этого поста — лучше понять приведенный ниже код:
private val calfViewModel: CalfViewModel by viewModels {
CalfViewModelFactory((activity?.application as
CalfApplication).repository)
}
- Более конкретно я попытаюсь объяснить раздел кода
by viewModels {}
. Я отношусь к тому типу людей, которые работают в обратном порядке, сначала я заставляю код работать, а затем пытаюсь понять его. Надеюсь, к концу этой заметки и вы, и я будем лучше понимать, что происходит в нашей кодовой базе.
Ключевое слово by
.
- Если мы прочитаем документацию по viewModels, то здесь говорится
Returns a property delegate to access ViewModel by default scoped to this Fragment:
. Потрясающе!!! Но что именно представляет собойproperty delegate
? Ну, мы знаем, что все, что определено с помощью var/val, является свойством, а согласно документации Kotlin, ЗДЕСЬ все, что после ключевого словаby
, является делегатом. Таким образом, сочетание определения свойства и ключевого словаby
создает свойствоdelegate
. В документации дается более формальное определение синтаксиса, необходимого для создания свойства-делегата:val/var <property name>: <Type> by <expression>
. Свойство автоматически получает свой собственный геттер и сеттер, но когда мы используемby
, мы заявляем, что эти методы доступа (геттеры и сеттеры) предоставляются в другом месте, ониделегируются
. Мы делегируем эту работу явной функции, в нашем случае этоviewModels
. Следует также отметить, что мы используемval
, а неvar
, попробуйте поменять их местами в своем коде и обратите внимание на ошибку, которую вы получите.
Что такое viewModels{}
- Из документации ЗДЕСЬ мы можем узнать, что
viewModels
относится к категорииextension function
. Так что же такое функция расширения?
Функция расширения
- Одной из главных тем Kotlin является плавная интеграция с существующим кодом. Даже чистые проекты Kotlin строятся поверх библиотек Java (Android — один из них). Функции расширения вступают в игру, потому что они позволяют нам использовать все тонкости Kotlin без необходимости их переписывать. Концептуально функция расширения — это функция, которая может быть вызвана как член класса, но определена вне его.
- Таким образом, мы знаем, что viewModels{} — это функция расширения, определенная вне класса
androidx.fragment.app
, но позволяющая нам вызывать ее из него. - Далее мы должны поговорить о фигурных скобках.
Фигурные скобки {}
.
- Для того чтобы рассказать о фигурных скобках, нам необходимо кратко поговорить о лямбда-выражениях. Лямбда-выражение определяется как
литерал функции
, а литералы функции — это функции, которые не объявляются, а передаются сразу как выражение. Мы всегда можем определить лямбда-выражение, потому что они всегда окружены фигурными скобками. Поэтому в нашем примере все, что находится внутри{}
, считаетсялямбда-выражением
. - Следует отметить, что кусок кода в фигурных скобках является лямбда-выражением, и мы передаем его в качестве аргумента в функцию. В нашем случае это функция
viewModels
. Причина отсутствия правильного вызова функции, например,viewModels(){}
, заключается в том, что в любом случае, когда лямбда является единственным аргументом функции, мы можем убрать пустые круглые скобки из вызова. В нашем лямбда-выражении последнее выражение внутри тела лямбды рассматривается как возвращаемое значение.
Заключение
- Спасибо, что нашли время прочитать эту статью в моем блоге. Если у вас возникли вопросы или проблемы, пожалуйста, комментируйте их ниже или свяжитесь со мной в Twitter.