0Pricing
Kotlin Academy · Урок

Копирование с помощью copy() и частичные переопределения

Используйте copy(), чтобы создавать изменённые экземпляры, не изменяя исходный.

«Копирование с помощью copy() и частичные переопределения» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Неизменяемое обновление с помощью copy()

copy() создаёт новый экземпляр класса данных с изменёнными свойствами. Все свойства, для которых не указаны новые значения, сохраняют исходные значения.

Основы copy()

Передавайте именованные аргументы, чтобы переопределить нужные свойства.
data class Person(val name: String, val age: Int, val city: String)
val alice = Person("Alice", 30, "Berlin")
val olderAlice = alice.copy(age = 31)
println(olderAlice)  // Person(name=Alice, age=31, city=Berlin)

Копирование нескольких полей

Переопределяйте любое необходимое количество полей.
data class Config(val host: String, val port: Int, val ssl: Boolean, val timeout: Int)
val prod = Config("prod.server", 443, true, 30)
val test = prod.copy(host = "test.server", port = 8080, ssl = false)
println(test)

copy не изменяет исходный объект

copy всегда создаёт новый объект. Исходный объект полностью остаётся без изменений.
data class Point(val x: Int, val y: Int)
val origin = Point(0, 0)
val moved = origin.copy(x = 5)
println(origin)  // Point(x=0, y=0) — unchanged
println(moved)   // Point(x=5, y=0)

Оговорка о глубоком копировании

copy выполняет поверхностное копирование. Изменяемые объекты внутри класса данных являются общими для исходного объекта и его копии.
data class Team(val name: String, val members: MutableList<String>)
val t1 = Team("A", mutableListOf("Alice"))
val t2 = t1.copy(name = "B")
t2.members.add("Bob")       // modifies SHARED list!
println(t1.members)  // [Alice, Bob] ← also changed!

Как избежать проблем поверхностного копирования

Используйте неизменяемые данные внутри классов данных, чтобы избежать проблем с общим состоянием.
data class Team(val name: String, val members: List<String>)  // immutable list
val t1 = Team("A", listOf("Alice"))
val t2 = t1.copy(name = "B", members = t1.members + "Bob")
println(t1.members)  // [Alice]
println(t2.members)  // [Alice, Bob]

copy в управлении состоянием

copy — идиоматичный способ обновления состояния в архитектурах в стиле Redux или MVI.
data class UiState(val loading: Boolean, val items: List<String>, val error: String?)
fun reduce(state: UiState, action: Action) = when (action) {
    is Loading -> state.copy(loading = true)
    is Success -> state.copy(loading = false, items = action.data)
    is Error -> state.copy(loading = false, error = action.msg)
}

copy с параметрами по умолчанию

Даже у классов данных со множеством свойств copy остаётся удобным благодаря именованным параметрам.
data class Article(
    val id: Long, val title: String, val body: String,
    val published: Boolean = false, val views: Int = 0
)
val draft = Article(1L, "Hello", "Content...")
val published = draft.copy(published = true)
println(published.title)  // Hello

Использование copy в тестах

copy упрощает создание тестовых данных: создайте один базовый объект и изменяйте только нужные поля.
val baseUser = User(id = 1, name = "Test", email = "test@test.com", active = true)
val inactiveUser = baseUser.copy(active = false)
val renamed = baseUser.copy(name = "Renamed")

copy и шаблон Builder

copy() в классе данных — ответ Kotlin на шаблон Builder. Для сложных объектов с множеством необязательных полей сочетание класса данных и copy получается более лаконичным.
// Java Builder:
User.builder().name("A").age(30).role("admin").build()
// Kotlin:
val u = User("A", 30, "admin")  // or copy from base

Семантика записей

Классы данных со свойствами val ведут себя подобно записям Java (JDK 16+): они неизменяемы, основаны на значениях и автоматически преобразуются в печатное представление.
data class RGB(val r: Int, val g: Int, val b: Int)
val white = RGB(255, 255, 255)
println(white)  // RGB(r=255, g=255, b=255)

Быстрая проверка

Что происходит с исходным экземпляром класса данных, когда Вы вызываете для него copy()?

Повторение

copy() создаёт новый экземпляр с переопределёнными полями, а исходный объект остаётся без изменений. Это удобно для управления состоянием, тестов и создания объектов в стиле Builder. Остерегайтесь поверхностного копирования изменяемых свойств. Далее — деструктуризация!

Часто задаваемые вопросы

Урок «Копирование с помощью copy() и частичные переопределения» бесплатный?

Да — полный текст урока «Копирование с помощью copy() и частичные переопределения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Копирование с помощью copy() и частичные переопределения»?

Используйте copy(), чтобы создавать изменённые экземпляры, не изменяя исходный. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Копирование с помощью copy() и частичные переопределения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы классов данных: автоматически создаваемые методы
  2. Копирование с помощью copy() и частичные переопределения
  3. Деструктурирующие объявления с componentN
  4. Классы данных в коллекциях и в качестве ключей карт
← Назад к Kotlin Academy