개요

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

+ Recent posts