Метод copyWith в Dart
Присваивание объекта другой переменной копирует
ссылку, а не отдельный экземпляр - исходный и новый
указатель делят одни и те же поля. Метод copyWith
создает новый объект с теми же полями, что и исходный.
В вызове можно указать только те параметры, которые
нужно заменить - остальные возьмутся из текущего
значения через ??:
class Post {
final String title;
final int likes;
const Post(this.title, this.likes);
Post copyWith({String? title, int? likes}) {
return Post(title ?? this.title, likes ?? this.likes);
}
@override
String toString() => "Post($title, $likes)";
}
Создадим объект и вызовем метод:
var ann = Post("Ann", 25);
var older = ann.copyWith(likes: 26);
print(older);
Исходный объект не меняется: copyWith возвращает
отдельный экземпляр. Так удобно обновлять записи
с final-полями, не нарушая неизменяемость:
class Settings {
final String theme;
final String lang;
Settings(this.theme, this.lang);
Settings copyWith({String? theme, String? lang}) {
return Settings(
theme ?? this.theme,
lang ?? this.lang,
);
}
@override
String toString() => "Settings($theme, $lang)";
}
Создадим объект и вызовем метод:
var base = Settings("light", "en");
var dark = base.copyWith(theme: "dark");
print(base.theme);
print(dark.theme);
Имена аргументов в copyWith совпадают с именами
полей. Можно передать несколько полей сразу,
если нужно изменить больше одного значения:
class Job {
final String role;
final int level;
Job(this.role, this.level);
Job copyWith({String? role, int? level}) {
return Job(role ?? this.role, level ?? this.level);
}
@override
String toString() => "Job($role, $level)";
}
Создадим объект и вызовем метод:
var j = Job("dev", 1);
var promoted = j.copyWith(role: "lead", level: 2);
print(promoted);
Сделайте класс Price с полями
label и amount.
Дан объект:
var old = Price("basic", 10);
Получите копию объекта с тем же label
и amount = 15. Выведите на экран оба
объекта в двух строках.
Сделайте класс Route с полями
from, to, stops.
Создайте маршрут "A" - "B"
с 0 остановками. Получите копию
маршрута с stops = 2 и выведите на
экран только новый объект.