Котлиновский синтаксис
val (name, age) = user выглядит сексуально. Python-style, кратко, молодежно.Но для бизнес-логики это мина замедленного действия.
Представим классический DTO для транзакции:
data class Transaction(
val amount: Double,
val fee: Double
)
Где-то в недрах UseCase вы пишете:
val (total, commission) = getTransaction()
// Логика: total - commission
Всё работает.
Пока через полгода другой разработчик (или вы же) не решит, что поля в дата-классе должны идти в алфавитном порядке, или просто добавит новое поле в начало конструктора.
Изменение:
data class Transaction(
val fee: Double, // 👈 Поменяли местами
val amount: Double
)
Результат:
Код компилируется. Тесты (если они мокали объект, а не порядок полей) могут пройти.
Но в продакшене
total теперь равен fee, а commission равна amount.Поздравляю, вы только что начислили пользователю комиссию вместо зарплаты.
Почему это происходит?
Деструктуризация в Kotlin не смотрит на имена переменных. Она тупо вызывает
component1(), component2().Если типы полей совпадают (как
Double и Double выше) - компилятор молчит.✅ Правило Сеньора:
Используйте деструктуризацию только для:
1.
Pair и Triple (где порядок очевиден из названий first/second).2.
Map.Entry в циклах.3. Локальных переменных, которые живут 2 строчки кода.
Для всего остального (особенно Domain Models и DTO) - только явный доступ к свойствам:
val total = tx.amountУ кого в проекте уже настроен Detekt на запрет деструктуризации? 👇
✍️ @kotlin_lib