Class | Strcut | Enum

Zeto·2022년 2월 23일
0

Swift_Study

목록 보기
1/18

| 클래스와 구조체, 그리고 열거형의 차이점

참조 타입 VS 값 타입 ?

Swift에서 보통 비교가 되는 대상 Class와 Struct로 이들을 언제 사용해야 될 지 항상 고민될 수 밖에 없다. 이와 함께 자주 쓰이는 자료구조로는 열거형으로 불리는 Enum이 존재한다. 이들을 비교할 때, 가장 간단하게 정리할 수 있는 것이 참조 타입이냐 값 타입이냐라는 부분이라 할 수 있다.

  • Class
    기존 인스턴스가 가지고 있는 데이터는 값 자체가 아닌, 해당 데이터의 메모리 포인터. 값이 아닌 메모리 포인터를 전달하기 때문에 데이터를 전달받은 곳에서 값을 변경하면 모든 인스턴스들도 영향을 받는다.
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
    데이터는 그 자체의 값을 가지고 있다. 데이터를 전달할 때, 해당 값의 복사본을 전달하기 때문에 이를 받은 곳에서 데이터를 변경해도 원본에는 아무런 영향이 없다. 이러한 특성때문에 Struct는 고유한 값을 가진다고 말한다.
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
    그룹에 대한 연관 값을 정의하고 사용하는 것이 가능한 타입으로서 항목 자체가 고유의 값이다.
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 구문과 합쳐질 때 가독성과 간결성이 높아지며, 생성하지 않아도 상수로 접근할 수 있다. 즉 사용성이 높은 측면이 있기 때문에 이 부분이 중요시 될 때 이용하는 것이 좋을 듯 하다.

profile
중2병도 iOS가 하고싶어

1개의 댓글

comment-user-thumbnail
2022년 2월 24일

(추가) Class 인스턴스를 let으로 선언하는 것은 참조 주소값을 고정하겠다는 의미이고, Struct를 let으로 선언하는 것은 실제값을 고정하겠다는 의미.

답글 달기