깊은 복사(Deep Copy), 얕은 복사(Shallow Copy), 그리고 중간 복사는 프로그래밍에서 객체를 복사하는 방법에 따라 객체의 복사된 데이터가 어떻게 동작하는지를 설명하는 개념입니다. 각 개념은 객체 내부의 참조 관계와 복사되는 방식에 차이가 있습니다.
1. 얕은 복사(Shallow Copy)
얕은 복사는 객체의 최상위 필드만 복사하는 방식입니다. 객체 내에 있는 필드들이 기본 자료형(숫자, 문자열 등)이면 값 자체가 복사되지만, **참조 타입(리스트, 맵, 객체 등)**이 있을 경우 참조(주소)만 복사됩니다. 즉, 내부 객체는 원본과 복사본이 같은 객체를 가리키게 됩니다.
예시 (Dart):
void main() {
var original = [1, 2, [3, 4]];
var shallowCopy = List.from(original);
shallowCopy[0] = 99; // 얕은 복사된 첫 번째 값 변경
shallowCopy[2][0] = 999; // 얕은 복사된 리스트 내부의 리스트 값 변경
print(original); // [1, 2, [999, 4]]
print(shallowCopy); // [99, 2, [999, 4]]
}
shallowCopy[2][0]
을 수정했을 때, 원본 리스트의 내부 리스트 값도 변경된 것을 볼 수 있습니다. 이는 얕은 복사가 내부 참조를 공유하기 때문입니다.
2. 깊은 복사(Deep Copy)
깊은 복사는 객체 내의 모든 필드와 그 필드가 가리키는 객체까지 재귀적으로 모두 복사하는 방식입니다. 즉, 원본 객체와 복사본 객체는 독립적인 객체가 됩니다. 깊은 복사는 복사본과 원본이 전혀 상관없는 별도의 객체로 존재하기 때문에, 하나를 수정해도 다른 쪽에 영향을 주지 않습니다.
예시 (Dart):
import 'dart:convert';
void main() {
var original = [1, 2, [3, 4]];
var deepCopy = jsonDecode(jsonEncode(original)); // 깊은 복사를 위해 JSON으로 변환 후 다시 디코딩
deepCopy[0] = 99; // 깊은 복사된 첫 번째 값 변경
deepCopy[2][0] = 999; // 깊은 복사된 리스트 내부의 리스트 값 변경
print(original); // [1, 2, [3, 4]] -> 원본은 그대로 유지
print(deepCopy); // [99, 2, [999, 4]] -> 깊은 복사된 리스트만 변경됨
}
- 깊은 복사에서는 내부 리스트도 새로 복사되었기 때문에,
deepCopy[2][0]
을 수정해도 원본 리스트는 변경되지 않습니다.
3. 중간 복사?
중간 복사는 정식 용어는 아니지만, 부분적으로 깊은 복사와 부분적으로 얕은 복사를 혼합한 방식을 가리킬 수 있습니다. 예를 들어, 특정 필드는 깊은 복사를 하고, 다른 필드는 얕은 복사를 하는 방식입니다. 객체의 특정 구조나 요구사항에 맞게 복사의 깊이를 조절하는 방법이라고 볼 수 있습니다.
예시 (Dart):
void main() {
var original = [1, 2, [3, 4]];
var middleCopy = List.from(original); // 얕은 복사
middleCopy[2] = List.from(original[2]); // 내부 리스트는 깊은 복사
middleCopy[0] = 99;
middleCopy[2][0] = 999;
print(original); // [1, 2, [3, 4]] -> 원본 내부 리스트는 변경되지 않음
print(middleCopy); // [99, 2, [999, 4]] -> 중간 복사된 리스트만 변경됨
}
middleCopy[2] = List.from(original[2]);
를 통해 내부 리스트만 깊은 복사하고, 나머지는 얕은 복사합니다. 즉, 내부 리스트만 독립적으로 관리할 수 있는 구조입니다.
결론
- 얕은 복사: 객체의 최상위 필드만 복사되며, 내부 참조 객체는 원본과 복사본이 동일한 객체를 가리킵니다.
- 깊은 복사: 객체의 모든 필드와 내부 객체까지 완전히 새롭게 복사되어, 원본과 복사본이 완전히 독립적으로 동작합니다.
- 중간 복사: 특정 필드는 얕은 복사, 특정 필드는 깊은 복사로 처리하여 복사의 깊이를 조절하는 방식입니다.
이 세 가지 복사 방식은 객체의 구조와 복사된 객체가 어떻게 동작해야 하는지에 따라 적절히 선택해 사용할 수 있습니다.
Share article