Как добавить шестой компонент в список компонентов Kotlin
Что проверяют
Это вопрос про деструктуризацию. У List в стандартной библиотеке есть только component1()…component5(), поэтому val (a, b, c, d, e, f) = list не компилируется. Проверяют, знаете ли вы, что за деструктуризацией стоят операторные функции componentN(), и умеете ли их дописать. Следом спрашивают, почему у data class такого ограничения нет.
Как отвечать
Объясните механику. Запись val (x, y) = obj компилятор превращает в val x = obj.component1() и val y = obj.component2(). Это работает с любым типом, у которого есть функции с модификатором operator и нужными именами, будь то член класса или расширение.
Для списков и массивов стандартная библиотека объявляет расширения component1()…component5(). Шестое добавляете сами:
operator fun <T> List<T>.component6(): T = get(5)
val (a, b, c, d, e, f) = listOf(1, 2, 3, 4, 5, 6)Дальше контекст, который отличает сильный ответ:
- data class: компилятор генерирует
componentN()для каждого свойства первичного конструктора, поэтому их может быть сколько угодно; - короткий список: если элементов меньше шести,
get(5)броситIndexOutOfBoundsExceptionв рантайме, длину списка компилятор не знает; - массивы: у
Arrayтот же предел в пять компонентов, расширение для него объявляется отдельно.
Шесть позиционных переменных из списка обычно сигнал к рефакторингу. Если у элементов есть смысл, в Android-коде лучше завести data class, например для состояния экрана в ViewModel: поля получат имена, и никому не придётся гадать, что лежит в пятой позиции.
Где спотыкаются
Отвечают про mutableListOf и add(). Добавить элемент в список умеет каждый, вопрос не об этом. Если формулировка кажется странной, уточните её, но деструктуризацию стоит узнать сразу.
Пишут расширение без operator. Функция существует, но компилятор не использует её для деструктуризации и выдаёт ошибку.
Путают componentN() с индексом и ждут, что component6() вернёт шестой элемент любой коллекции, включая Set или Map. Для них позиционных компонентов в стандартной библиотеке нет, а у Map.Entry только component1() и component2(), то есть ключ и значение.