Ответ
Да, лямбда может быть свойством в data class. Однако, нужно учитывать несколько нюансов:
- Лямбда не учитывается в автоматически генерируемых методах (
equals(),hashCode(),toString()). - Если лямбда участвует в
copy(), поведение может быть неожиданным из-за захвата контекста.
Пример:
data class User(
val name: String,
val onAction: () -> Unit
)
fun main() {
val user1 = User("Alice", { println("Hi!") })
val user2 = User("Alice", { println("Hello!") })
println(user1 == user2) // true, так как лямбды игнорируются
} Ответ 18+ 🔞
Эй, а вот это уже интересный вопрос! Слушай, ты когда-нибудь пытался запихнуть лямбду в data class? Это как пытаться засунуть кота в стиральную машинку — вроде влазит, но потом получаешь такие сюрпризы, что просто ёпта.
Ну, формально-то можно, конечно. Объявил свойство типа () -> Unit, и вроде бы всё компилируется, красота. Но тут начинается самое весёлое, я тебе щас расскажу, чувак.
Первое, о чём нужно помнить — это пизда рулю с теми самыми автоматическими методами, за которые мы все так любим data class. equals(), hashCode(), toString() — они эту твою лямбду в хуй не ставят. Совсем. Игнорируют, как будто её нет. Смотри, вот пример, от которого сам от себя охуел в первый раз:
data class User(
val name: String,
val onAction: () -> Unit // Вот эта хитрая жопа
)
fun main() {
val user1 = User("Alice", { println("Hi!") })
val user2 = User("Alice", { println("Hello!") }) // Лямбда-то другая, блядь!
println(user1 == user2) // Выведет true! Потому что лямбды игнорируются!
}
Представляешь? Два разных User с разным поведением, а equals() говорит, что они одинаковые! Доверия ебать ноль к такой логике. Это как сравнивать два автомобиля только по цвету, а то, что у одного двигатель есть, а у другого — нет, да похуй.
А теперь про copy(). Вот это вообще ёперный театр. Если твоя лямбда что-то захватывает из внешнего контекста (замыкание, все дела), то при копировании может случиться такое, что волнение ебать. Можешь получить неочевидное поведение, потому что копируется ссылка на ту же самую лямбду, со всеми её захваченными переменными. Не тот случай, когда хочется сюрпризов.
Так что да, технически — можно. Практически — нужно десять раз подумать, э бошка думай. Чаще всего, если тебе нужен data class с поведением, то лямбду как свойство — это манда с ушами. Лучше вынести её в отдельный интерфейс или использовать функцию высшего порядка отдельно. А data class пусть занимается своим делом — хранит данные, которые можно честно сравнивать и копировать. Иначе потом будешь сидеть и думать: «Какого хуя у меня два разных объекта считаются одинаковыми?». А ответ будет простой — потому что лямбда.