struct YoutuberStruct {
var name: String
var subscribersCount : Int
}
var devJ = YoutberStruct(name: "J", subscribersCount: 99)
var devJClone = devJ
print("devJClone.name : \(devJClone.name)")
devJClone.name = "HH"
print("devJClone.name : \(devJClone.name)")
스위프트에서는 데이터 타입에 따라 복사 방식이 다르다.
- 구조체 (Struct):
- 구조체는 값 타입(Value Type)이다.
- 구조체 인스턴스를 다른 변수나 상수에 할당하거나 함수에 전달할 때 깊은 복사(Deep Copy)가 발생한다.
- 즉, 실제 값이 복사되어, 복사된 인스턴스와 원본 인스턴스는 독립적인 메모리 위치에 저장된다. 둘 중 하나를 변경하더라도 다른 하나에는 영향을 주지 않는다.
- 클래스 (Class):
- 클래스는 참조 타입(Reference Type)이다.
- 클래스 인스턴스를 다른 변수나 상수에 할당하거나 함수에 전달할 때 얕은 복사(Shallow Copy) 또는 참조 복사(Reference Copy)가 발생한다.
- 이는 메모리 위치의 참조가 복사되므로, 복사된 인스턴스와 원본 인스턴스는 동일한 메모리 위치를 참조한다. 따라서 둘 중 하나를 변경하면 다른 하나도 영향을 받는다.
이러한 차이로 인해, 상황과 필요에 따라 클래스나 구조체 중 적절한 것을 선택하여 사용하게 된다.
스위프트의 클래스와 구조체는 여러 차이점을 가지고 있다. 아래는 주요 차이점이다:
- 참조 타입 vs 값 타입:
- 클래스(Class): 참조 타입(Reference Type). 하나의 클래스 인스턴스를 여러 변수/상수가 참조할 수 있음.
- 구조체(Struct): 값 타입(Value Type). 각 변수/상수는 구조체의 새로운 복사본을 가짐.
- 상속(Inheritance):
- 클래스: 다른 클래스에서 상속을 받을 수 있음. 이를 통해 부모 클래스의 속성과 메서드를 재사용하거나 오버라이드할 수 있음.
- 구조체: 상속을 지원하지 않음.
- 타입 캐스팅(Type Casting):
- 클래스: 실행 시간에 인스턴스의 타입을 확인하거나 다른 클래스로 타입 캐스팅이 가능함.
- 구조체: 이런 기능을 지원하지 않음.
- 디이니셜라이저(Deinitializer):
- 클래스: 인스턴스가 해제될 때 사용할 수 있는 디이니셜라이저를 가질 수 있음.
- 구조체: 디이니셜라이저를 지원하지 않음.
- 참조 카운트(Reference Counting):
- 클래스: ARC(Automatic Reference Counting)를 사용하여 클래스의 인스턴스 참조를 관리함.
- 구조체: 참조 타입이 아니므로 참조 카운트에 영향을 주지 않음.
언제 어떤 것을 사용해야 할까?
- 구조체의 사용 시점:
- 데이터를 캡슐화하고, 복사 동작이 의도된 경우.
- 상속이나 여러 참조가 필요하지 않은 경우.
- 간단한 데이터 모델로 구성된 경우. 예: 2D 좌표 시스템, 간단한 데이터 모델 등.
- 클래스의 사용 시점:
- 상속과 오버라이딩이 필요한 경우.
- 참조 카운트와 같은 참조 타입의 기능이 필요한 경우.
- 다른 객체와 상호 작용하는 복잡한 객체를 생성할 때. 예: UI 컴포넌트, 대규모 데이터 모델 등.
이런 기준을 바탕으로 상황과 요구 사항에 따라 적절한 선택을 하게 된다.
DB와 연동하는 엔티티나 DTO(Data Transfer Object)와 같은 객체를 설계할 때 클래스와 구조체 중 어떤 것을 선택할지는 여러 상황과 요구 사항을 고려해야 한다.
- DB와 연동하는 엔티티:
- 엔티티는 데이터베이스의 테이블과 일대일로 매핑되는 객체이다.
- 엔티티는 변경되는 상태와 참조의 관점에서 보았을 때 클래스(참조 타입)를 사용하는 것이 적절하다.
- 특히 ORM(Object-Relational Mapping) 도구와 연동할 때, 변경 추적(예: dirty checking) 및 lazy loading과 같은 기능을 활용할 수 있다. 이런 기능은 참조 타입인 클래스와 잘 맞다.
- DTO(Data Transfer Object):
- DTO는 일반적으로 계층 간의 데이터 전송을 위해 사용된다. (예: 서비스 레이어와 UI 레이어 간의 데이터 전송)
- DTO는 상태 변경이나 특별한 로직 없이 순수한 데이터를 전달하는 목적을 가진다.
- DTO에서는 데이터의 불변성을 보장하기 위해 구조체(값 타입)를 사용하는 것이 좋을 수 있다.
- 그러나 특정 상황에서 참조 타입의 특징이 필요하다면 클래스도 고려할 수 있다.
결과적으로, 엔티티는 대부분의 경우 클래스로, DTO는 상황에 따라 클래스나 구조체로 구현하는 것이 일반적이다. 하지만 사용하는 프레임워크나 라이브러리, 구현하려는 시스템의 특성에 따라 이러한 선택이 달라질 수 있다. 따라서 구현하려는 시스템의 전반적인 아키텍처와 요구 사항을 고려하여 결정하는 것이 중요하다.