| 클래스와 구조체, 그리고 열거형의 차이점
참조 타입 VS 값 타입 ?
Swift에서 보통 비교가 되는 대상 Class와 Struct로 이들을 언제 사용해야 될 지 항상 고민될 수 밖에 없다. 이와 함께 자주 쓰이는 자료구조로는 열거형으로 불리는 Enum이 존재한다. 이들을 비교할 때, 가장 간단하게 정리할 수 있는 것이 참조 타입이냐 값 타입이냐라는 부분이라 할 수 있다.
class Person{
var name: String
init(name: String){
self.name = name
}
}
var zeto = Person(name: "Zeto")
var nana = zeto
nana.name = "Nana"
// 동일한 인스턴스를 참조하고 있으므로 zeto.name 또한 Nana로 변경됨
struct Person{
var name: String
init(name: String){
self.name = name
}
}
var zeto = Person(name: "Zeto")
var nana = zeto
nana.name = "Nana"
// 복사된 값을 전달받은 것이므로 zeto.name은 그대로 Zeto를 유지
enum Person{
case korean
case japanese
case american
}
var korean = Person.korean
위와 같이 Class와 Struct는 각각 참조 타입과 값 타입으로서 분명한 차이를 보여주기 때문에 두 자료구조의 차이점으로 주요한 차이로 손꼽힌다. 다만 실제로는 Class와 Struct가 섞여져서 사용되는 경우가 많으므로 무조건 해당 타입의 방식대로만 작동한다고 단정지을 수는 없다. (특히 Struct 내의 타입이 Class일 경우에는 Struct 내의 데이터 값이 고유하지 않게 되는 경우가 생김)
Enum 또한 값 타입이기는 하나 직접적인 비교 측면에서는 보통 Class와 Struct를 많이 대조하기 때문에 약간 뒤로 밀려나게 되었다ㅠㅠ
그 외에도 Class는 상속과 deinitializer가 존재하고 heap 영역에 저장된다. Struct는 기본적으로 stack 영역에 저장(상황에 따라 heap에도 저장됨), 상속 불가. Enum 또한 상속이 불가하고 rawValue를 통해 원시값을 지정할 수 있다는 등의 차이점 등을 가지고 있다.
| 클래스와 구조체, 그리고 열거형의 사용
대체 언제 사용해야 되는 걸까 ?
보통 Struct를 사용하는 경우에 대한 정의는 아래와 같다.
- 연관된 몇몇의 값들을 모아서 하나의 데이터타입으로 표현하고 싶을 때
- 다른 객체나 함수 등에 전달 시, 참조가 아닌 복사를 원할 때
- 자신을 상속할 필요가 없거나 다른 타입을 상속받을 필요가 없을 때
- Apple 프레임워크에서 프로그래밍을 할 때에는 주로 클래스를 많이 사용한다
다만 실제로 자료구조를 Struct로 설계할 것인지 Class로 설계할 것인지 마주한 상황에서는 해당 정의가 딱 와닿지 않을 가능성이 높다. 따라서 저런 정의나 Class / Struct 특성들을 고려하여 자신이 납득할 수 있는 커스텀 정의를 만드는 것도 중요하다고 생각된다.
본인의 경우에는 Struct가 값에 중점을 두고 고유의 값을 지닌다는 데에 초점을 두고 데이터의 변경이 잦거나 다른 인스턴스들과의 교류가 빈번할 경우에는 Class로 데이터의 변경이 적고 해당 데이터의 값의 접근이 중점일 경우에는 Struct로 설계하고자 생각했다.
(본인 뇌피셜이니 건전한 지적은 감사합니다^^)
마지막으로 Enum의 경우에는 switch 구문과 합쳐질 때 가독성과 간결성이 높아지며, 생성하지 않아도 상수로 접근할 수 있다. 즉 사용성이 높은 측면이 있기 때문에 이 부분이 중요시 될 때 이용하는 것이 좋을 듯 하다.
(추가) Class 인스턴스를 let으로 선언하는 것은 참조 주소값을 고정하겠다는 의미이고, Struct를 let으로 선언하는 것은 실제값을 고정하겠다는 의미.