2022.10.06

22강. 스프레드 연산자(깊은복사, 값변경, 값추가)

  dart에는 spread 연산자가 있어서 타언어보다 쉽게 깊은 복사가 가능하다.

void main() {
  var list = [1,2,3];
  var newList = [...list];
  
  print(list);
  print(newList);
  
  list[0] = 10;
  print(list);
  print(newList);
}

  결과에서 보이는 것처럼 스프레드 연산자를 이용하여 복사를 하면 레퍼런스 복사(메모리 주소를 복사)가 아닌 데이터 값자체를 복사해오는 깊은 복사를 한다. 타언어에서 깊은 복사를 할때와 비교해보면 굉장히 수월하게 깊은 복사를 수행할 수 있다.

  하지만 주의해야할 것이 있는데...

void main() {
  var list = [{"id":1}, {"id":2}];
  var subList = list;
  var newList = [...list];
  
  print(list);
  print(newList);
  
  list[0]["id"] = 10;
  print(list);
  print(newList);
  
  print(list.hashCode);
  print(newList.hashCode);
  print(subList.hashCode);
}

  위와 같이 맵을 스프레드 연산자로 복사하게 되면 분명 메모리 주소는 다른 깊은 복사를 하는데 list의 값을 변경시켰을 때 newList의 값도 변경되는 현상이 일어난다. 이것은 list 객체 자체는 깊은 복사를 하지만 내부에 있는 map을 얕은복사를 하기 때문에 나타나는 현상이다.

이를 해결하기 위해서는

var newList = list.map((i)=>{...i}).toList();

와 같이 리스트에 있는 맵을 람다식으로 하나하나 찾아서 스프레드 연산을 해야한다.

스프레드 연산을 활용하면 단순히 복사뿐만 아니라 삽입, 삭제와 수정도 할 수 있다.

void main() {

	// 수정
  var users = [
    {"id":1, "username":"thekim12", "password":1234},
    {"id":2, "username":"metacoding", "password":5678},
  ];
  
  var newUsers = users.map((i)=>i["id"]==2 ? {...i, "username":"love"}: i).toList();
  print(newUsers);
  
  // 삽입
  var test = [1,2,3,4];
  var newTest = [...test, 5];
  print(newTest);
  
}

0개의 댓글