Комментарии 13
Зачем делать свойство-расширение с типом лямбды? Почему не просто метод-расширение?
0
В этом случае свойство-расширение включает два пространства имен (в моем случае и View, и Data)
val Data.bindMethod_cell_2: View.() -> Unit
get() = {
//cell2_icon принадлежит View, icon принадлежит Data, а функция обращается к обоим свойствам без префиксов view. и data.
cell2_icon.setImageResource(icon)
cell2_text.setText(titleId)
}
0
Ну это почти то же самое что и
Ради чего? Избавиться от явных имён переменных? Зато усложнить само объявление функции. И теперь вместо простого метода у вас в байткоде добавится новый анонимный класс.
Какой-то перебор во всём.
fun Data.bindMethod_cell_2(view: View) {
view.cell2_icon.setImageResource(icon)
view.cell2_text.setText(titleId)
}
Ради чего? Избавиться от явных имён переменных? Зато усложнить само объявление функции. И теперь вместо простого метода у вас в байткоде добавится новый анонимный класс.
Какой-то перебор во всём.
0
Если цель просто иметь доступ к переменным двух классов, то чем вас не устроил «apply»?
fun Data.bindCell1(view: View) = view.apply{
cell1_icon.setImageResource(icon)
cell2_text.setText(titleId)
}
0
Всем, но тогда пример бы не получился. В аннотации я указал, что статья не стиля программирования ради, а для описания возможностей языка.
+1
Нельзя оценить выразительность языка в полной мере, если рассматривать неудачные примеры. К сожалению, у вас в статье описанные возможности и правда используются не по назначению. Единственного apply было бы достаточно.
0
На самом деле apply внутри состоит из схожего метода.
Но опять же, для наглядности написал свой.
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
Но опять же, для наглядности написал свой.
0
> cell2_icon.setImageResource(icon)
А только меня смущает, что из кода теперь невозможно понять к какому классу относится «icon», ко view или к data?
Если эта информация просто теряется — это не выразительность, это наоборот, обфускация. И потенциальный источник ошибок.
А только меня смущает, что из кода теперь невозможно понять к какому классу относится «icon», ко view или к data?
Если эта информация просто теряется — это не выразительность, это наоборот, обфускация. И потенциальный источник ошибок.
0
В Kotlin, если использовать подобные конструкции, однозначно нужно использовать преффикс (вроде cell2_ в cell2_icon) в именах элементов лайаута. Потому что как раз в них крайне легко накосячить с импортом сгенерированного обращения и получить NullPointer. Одновременно с этим он и позволяет избежать обфучкации конкретно в моем примере.
В целом, в своих проектах объединение нескольких пространств имен я практикую только в заранее безопасных вариантах — model (набор переменных) и view (набор переменных с префиксами), модель и сервис (набор методов), модель логику (набор методов вроде process_ и show_).
Объединение пространств имен, как и множественное наследование, однозначно не является рекомендуемой практикой и должно подкрепляться пониманием программиста, что и зачем он делает. Тот самый случай, когда проще совсем не значит лучше.
Именно мой пример я считаю безопасным в использовании, т.к. префиксы более я нигде не использую, кроме имен отображаемых элементов.
В целом, в своих проектах объединение нескольких пространств имен я практикую только в заранее безопасных вариантах — model (набор переменных) и view (набор переменных с префиксами), модель и сервис (набор методов), модель логику (набор методов вроде process_ и show_).
Объединение пространств имен, как и множественное наследование, однозначно не является рекомендуемой практикой и должно подкрепляться пониманием программиста, что и зачем он делает. Тот самый случай, когда проще совсем не значит лучше.
Именно мой пример я считаю безопасным в использовании, т.к. префиксы более я нигде не использую, кроме имен отображаемых элементов.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Выразительный Kotlin. Extensions