개요
Spread 연산자(...)는 Dart 2.3 버전에서 도입된 기능으로, 컬렉션의 요소들을 다른 컬렉션에 편리하게 삽입할 수 있게 해주는 연산자입니다. 이번 포스트에서는 Spread 연산자의 다양한 사용법과 활용 사례에 대해 알아보겠습니다.
Spread 연산자
List에서의 사용
void main() {
var list1 = [1, 2, 3];
var list2 = [4, 5, 6];
// Spread 연산자를 사용하여 리스트 병합
var combined = [...list1, ...list2];
print(combined); // [1, 2, 3, 4, 5, 6]
// 개별 요소와 함께 사용
var withMore = [0, ...list1, 4];
print(withMore); // [0, 1, 2, 3, 4]
}
Set에서의 사용
void main() {
var set1 = {1, 2, 3};
var set2 = {3, 4, 5};
// Set 병합 (중복제거)
var combinedSet = {...set1, ...set2};
print(combinedSet); // {1, 2, 3, 4, 5}
}
Map에서의 사용
void main() {
var map1 = {'a': 1, 'b': 2};
var map2 = {'c': 3, 'd': 4};
// Map 병합
var combinedMap = {...map1, ...map2};
print(combinedMap); // {a: 1, b: 2, c: 3, d: 4}
// 충돌이 있는 경우 나중에 오는 값이 우선
var map3 = {'a': 5, 'e': 6};
var overrideMap = {...map1, ...map3};
print(overrideMap); // {a: 5, b: 2, e: 6}
}
Null-aware Spread 연산자 (...?)
void main() {
List<int>? nullableList;
var list = [1, 2, ...?nullableList];
print(list); // [1, 2]
nullableList = [3, 4];
list = [1, 2, ...?nullableList];
print(list); // [1, 2, 3, 4]
}
조건부 사용
void main() {
var items = [1, 2];
List<int>? extraItems;
// null이 아닐 때만 spread
var combined = [
...items,
if (extraItems != null) ...extraItems,
];
print(combined); // [1, 2]
}
Spread 활용
Flutter 위젯 트리에서의 활용
class MyWidget extends StatelessWidget {
final List<Widget>? optionalWidgets;
const MyWidget({Key? key, this.optionalWidgets}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Fixed Widget'),
...?optionalWidgets,
Text('Another Fixed Widget'),
],
);
}
}
데이터 모델 복사 및 업데이트
class User {
final String name;
final Map<String, dynamic> preferences;
User(this.name, this.preferences);
User copyWith({
String? name,
Map<String, dynamic>? extraPreferences,
}) {
return User(
name ?? this.name,
{
...preferences,
if (extraPreferences != null) ...extraPreferences,
},
);
}
}
API 응답 병합
Future<Map<String, dynamic>> fetchUserData() async {
final basicInfo = await fetchBasicInfo();
final preferences = await fetchPreferences();
final settings = await fetchSettings();
return {
...basicInfo,
'preferences': {...preferences},
'settings': {...settings},
};
}
더 자세히
중첩된 컬렉션
void main() {
var nested = [
[1, 2],
[3, 4],
[5, 6],
];
// 중첩 리스트 펼치기
var flattened = [
for (var list in nested) ...list,
];
print(flattened); // [1, 2, 3, 4, 5, 6]
}
메모리 사용
// 새로운 리스트 생성 - 메모리 사용
var newList = [...oldList]; // 전체 복사
// 참조만 생성 - 메모리 효율적
var reference = oldList; // 참조만 복사
대규모 컬렉션 처리
void processLargeCollections() {
var largeList1 = List.generate(10000, (i) => i);
var largeList2 = List.generate(10000, (i) => i + 10000);
// 메모리 사용량이 큼
var combined = [...largeList1, ...largeList2];
// 대안: Iterator 사용
var iterator = Chain([largeList1.iterator, largeList2.iterator]);
}
주의사항
타입 안전성
void main() {
List<int> numbers = [1, 2, 3];
List<String> strings = ['a', 'b', 'c'];
// 컴파일 에러: 타입 불일치
// List<int> combined = [...numbers, ...strings];
// 올바른 방법: dynamic 또는 Object 사용
List<dynamic> combined = [...numbers, ...strings];
}
Const 컨텍스트
// const 컨텍스트에서 사용 가능
const list1 = [1, 2, 3];
const list2 = [4, 5, 6];
const combined = [...list1, ...list2]; // OK
// 런타임 값에는 const 사용 불가
var runtime = [1, 2, 3];
const invalid = [...runtime]; // Error
결론
Spread 연산자는 컬렉션을 다룰 때 매우 유용한 도구입니다. 특히 Flutter 개발에서 위젯 트리를 구성할 때 자주 사용되며, 코드의 가독성과 유지보수성을 크게 향상시킬 수 있습니다. 다만, 대규모 컬렉션을 다룰 때는 메모리 사용량을 고려해야 하며, 타입 안전성에도 주의를 기울여야 합니다.
'Language > Flutter' 카테고리의 다른 글
[Dart] fold() 메소드 (0) | 2024.11.19 |
---|---|
[Flutter] 상태 관리 기초 - setState (0) | 2024.11.18 |
[Dart] Null Safety (0) | 2024.11.16 |
[Dart] var, dynamic, final, late, const 키워드 (0) | 2024.11.15 |
[Flutter] Widget의 크기제약 (0) | 2024.11.07 |