Почему функция componentN мусорная

Ответ

Функции componentN (например, component1(), component2() и т.д.) — это сгенерированные Kotlin-компилятором функции деструктуризации для data-классов. Они считаются «мусорными» по нескольким причинам:

  1. Непредсказуемость: Порядок компонентов зависит от порядка объявления свойств в классе. Изменение порядка полей сломает код, использующий деструктуризацию.
  2. Слабые гарантии: Нет проверки на null или валидации данных при деструктуризации.
  3. Плохая читаемость: component1() не говорит о том, какое поле извлекается, в отличие от явного обращения к свойству.

Пример:

data class User(val name: String, val age: Int)
val (name, age) = User("Alice", 30) // Деструктуризация
// Лучше явно:
val user = User("Alice", 30)
val name = user.name
val age = user.age

Ответ 18+ 🔞

А, ну это же классика! Слушай, про эти componentN функции — это вообще отдельная песня, ебать мои старые костыли. Выглядит-то вроде прикольно, но на деле — сплошная головная боль.

Вот представь: у тебя есть data-класс, простой как три копейки.

data class User(val name: String, val age: Int)

И ты такой: "О, класс! Сейчас я его красиво разберу на запчасти!"

val (name, age) = User("Alice", 30)

Вроде всё ок, ёпта. Красиво, лаконично. Но это только на первый взгляд, чувак. А теперь давай посмотрим, где собака зарыта, а точнее — где манда с ушами прячется.

Во-первых, порядок — это пиздец. Эти component1(), component2() — они жёстко привязаны к тому, как ты поля объявил. Захотел ты, скажем, age перед name поставить по новой бизнес-логике? Бум! И всё, твой красивый код деструктуризации, который в двадцати местах использовался, накрылся медным тазом. Теперь component1() — это уже возраст, а не имя. И вместо Алисы у тебя в name окажется число 30. Удивление пиздец! Полный распиздяй получается. Никакой стабильности, доверия ебать ноль.

Во-вторых, что там внутри? А нихуя не понятно! component1() — это что? Имя? Фамилия? Логин? ID хомяка? Чтобы это понять, надо бежать в объявление класса и глазами искать, какое поле первое. Э бошка думай! А если класс большой? А если его не ты писал? Сплошное мучение. Сравни с явным обращением: user.name — сразу ясно, что за свойство. Никаких загадок.

В-третьих, гарантий — нихуя. Ты разбираешь объект, а там вдруг null прилетел? Или данные кривые? Эти сгенерированные функции просто отдадут тебе то, что есть. Никакой дополнительной проверки, никакой валидации. Просто хуй с горы — лови, не нравится, сам разбирайся.

Так что, если хочешь мой совет — не гонись за этой якобы "красотой". Чаще всего лучше сделать просто и надёжно:

val user = User("Alice", 30)
val name = user.name // Вот это понятно!
val age = user.age   // И это понятно!

Да, строк больше. Зато терпения ебать не тратишь, когда через месяц или когда другой человек будет читать твой код. И ничего не сломается от перестановки полей в классе. Деструктуризацию оставь для каких-нибудь простых пар (key, value) из мапы или для кортежей, где риски минимальны. А для нормальных data-классов — не усложняй, вы ходите по охуенно тонкому льду.