swift에서 많이 쓰이는 데이터 타입인 Struct, Class, Enum은 많이 사용하지만 각자 어떤 역할, 차이점이 뭔지 정확히 몰랐었습니다. 이번 기회에 정확한 역할과 차이점을 정리해 보기로 했습니다.
먼저 가장 큰 차이점은 값 타입이냐, 참조 타입이냐 에 따라 분류 할 수 있습니다. 클래스는 참조 타입으로 Heap 영역에 저장되며 해당 메모리를 호출할 때 메모리의 주소값을 전달하여 값을 가져옵니다.
구조체와 열거형은 값 타입으로 Stack 영역에 저장되며 필요시에 메모리의 값이 복사되어 전달 됩니다.
즉, 쉽게 말해
하나의 객체를 복사할 때,
값 타입은 데이터 자체가 복사되어 여러개의 데이터를 가지게 되지만,
참조 타입은 하나의 객체의 메모리를 공유하여 주소만 전달하기 때문에 실제로는 하나의 데이터를 가지게 됩니다.
그럼 메모리 클래스가 무조건 이득인거 아니야? 라는 질문을 할 수 있습니다. 하지만 메모리 측면에서 클래스가 유리하지만 속도 측면에서는 반대입니다..
클래스는 참조 타입이기 때문에 Heap 영역에서 관리합니다. -> RC를 통해서 메모리를 관리하는게 이게 생각보다 무겁기 때문에 속도 측면에서 느릴 수 밖에 없습니다.
하지만 값 타입인 구조체와 열거형은 Stack 영역이기 때문에 메모리 관리가 보다 쉽습니다. -> 값이 들어있는 스택의 스코프가 종료되면 메모리가 자동 제거되기 때문에 RC와 같은 작업이 필요없어서 더 빠릅니다.(훨씬)
상속 또한 참조 타입에서만 일어나기 때문에 당연히 클래스에서만 가능합니다. 그럼 값 타입인 구조체와 열거형은 당연히 불가능 하겠죠?? 대신에 프로토콜을 통해 비슷하게 만들수는 있습니다.
참고) 상속은 단일객체만 상속이 가능하지만 프로토콜은 다중 채택이 가능하다.
열거형은 다른 언어와 다르게 swift에서는 고유한 타입으로 취급합니다. 열거형이 클래스와 구조체와의 차이점은 생성자를 가지지 않는다는 점입니다. 또한 열거형은 연관값을 구별되는 값을 할당하기 때문에 초기값을 설정하지 않아도 됩니다. 다음 코드와 같이 타입을 설정해준 열거형은 초기값(rawValue)를 가지게 됩니다.
enum A: Int {
case a // 초기값이 0
case b // 초기값이 1
case c // 초기값이 2
}
enum B: String {
case a // 초기값이 a
case b // 초기값이 b
case c // 초기값이 c
}
클래스, 구조체, 열거형의 공통점은 모두 데이터 타입으로 취급됩니다. 또한 확장(Extension) 가능합니다.