class User {
final String name;
final int? age;
User({required this.name, this.age});
User copyWith({String? name, int? age}) {
return User(name: name ?? this.name, age: age ?? this.age);
}
}
void main() {
User user1 = User(name: 'user1', age: 30);
print('name : ${user1.name} age : ${user1.age}');
User user2 = user1.copyWith(name: 'user2', age: null);
print('name : ${user2.name} age : ${user2.age}');
}
name : user1 age : 30
name : user2 age : 30
null을 전달하면 원래 값을 유지하도록 설계age : null을 명시적으로 넣으면 기존 값이 유지된다. -> null을 적용하고 싶을 때 문제가 생김class User {
final String name;
final int? age;
User({required this.name, this.age});
User copyWith({String? name, int? age, bool setAgeNull = false}) {
return User(
name: name ?? this.name,
age: setAgeNull ? null : (age ?? this.age),
);
}
}
void main() {
User user1 = User(name: 'user1', age: 30);
print('name : ${user1.name} age : ${user1.age}');
User user2 = user1.copyWith(name: 'user2', setAgeNull : true);
print('name : ${user2.name} age : ${user2.age}');
}
name : user1 age : 30
name : user2 age : null
copyWith를 통해서 null을 지정할 수 있다.boolean타입의 플래그를 추가하면 코드가 길어지고 관리가 복잡해진다.User copyWith({String? name, int? age, bool setAgeNull = false, String? email, bool setEmailNull = false}) {
return User(
name: name ?? this.name,
age: setAgeNull ? null : (age ?? this.age),
email: setEmailNull ? null : (email ?? this.email),
);
}boolean타입의 파라미터를 추가로 지정해줘야 한다.copyWith는 원하는 값만 전달하면 되는데, null을 지정하려면 추가적인 파라미터를 작성해야함. nullable 변수를 감싸는 래퍼 클래스를 만들어 null을 명시적으로 적용할 수 있게 하는 방식이다.
class NullWrapper<T> {
final T? value;
const NullWrapper(this.value);
}
class User {
final String name;
final int? age;
User({required this.name, this.age});
User copyWith({String? name, NullWrapper<int>? age}) {
return User(
name: name ?? this.name,
age: age == null ? this.age : age.value,
);
}
}
void main() {
User user1 = User(name: 'user1', age: 30);
print('name : ${user1.name} age : ${user1.age}');
User user2 = user1.copyWith(name: 'user2');
print('name : ${user2.name} age : ${user2.age}');
User user3 = user1.copyWith(name: 'user3', age : NullWrapper(null));
print('name : ${user3.name} age : ${user3.age}');
User user4 = user1.copyWith(name: 'user4', age : NullWrapper(20));
print('name : ${user4.name} age : ${user4.age}');
}
name : user1 age : 30
name : user2 age : 30
name : user3 age : null
name : user4 age : 20
null을 전달해도 기존 값 유지NullWrapper(null)을 전달하면 명확하게 null을 적용할 수 있다.copyWith를 사용할 때 NullWrapper(value)를 써야 하는 불편함 있음