티스토리 뷰

swift

[swift] Struct vs. Class

순진이 2022. 3. 29. 14:02

오늘도 강의를 통해 배운 강의 속 지식!

struct vs. class

다른 강의를 들을 때, 왠만하면 struct를 쓰라는 이야기를 들었었는데! 오늘 강의를 들으니, 훨씬 이해가 잘 갔다랄까요?

그래서 정리해봅니다!!

 

1. struct vs. class 복사

2. struct vs. class 인스턴스 상수/변수

 

 

시작해!!


1. struct vs. class 복사

우선 아래 두 개의 구조체와 클래스를 만들어줄게용!

 

<구조체의 영웅>

struct StructHero { 
    var name: String
    var universe: String
}

<클래스의 영웅>

class ClassHero {
    var name: String
    var universe: String
    
    init(name: String, universe: String) {
        self.name = name
        self.universe = universe
    }
}

 

 

이제 만든 struct와 class의 인스턴스를 찍어내고, 값을 복사해볼게요!

 

(1) struct 경우의 복사 (값 타입)

 

우선 struct는 "값타입"입니다. (value type)

복사 시, ""이 복사되는 거에요. 우리가 일반적으로 ctrl C + ctrl V하는 것과 같아요.

에엥? 당연한 소리를? 근데 이게 참조 타입인 class는 다르대요. 그건 아래 class를 다룰 때 얘기할게요!

var hero = StructHero(name: "Iron Man", universe: "Marvel")

var anotherMarvelHero = hero

anotherMarvelHero.name = "The Hulk"

print("hero name = \(hero.name)") // hero name = Iron Man
print("anotherMarvelHero name = \(anotherMarvelHero.name)") //anotherMarvelHero name = The Hulk

hero라는 struct의 인스턴스를 anotherMarvelHero라는 또 다른 인스턴스에 할당해볼게요.

각각의 이름을 print 해보았을 때는?

"값" 자체가 복사되기 때문에 hero와 anotherMarvelHero의 name 속성(property)이 다른 게 보이져?!

(hero = Iron Man / anotherMarvelHero = The Hulk)

 

우리 흔히 말하는 "복사"의 의미와 유사합니다.

 

 

그럼 class는 어떨까요?

(2) class 경우의 복사 (참조 타입)

똑같은 행위를 class의 인스턴스로 해볼게요.

var hero = ClassHero(name: "Iron Man", universe: "Marvel")

var anotherMarvelHero = hero

anotherMarvelHero.name = "The Hulk"

print("hero name = \(hero.name)") // hero name = The Hulk
print("anotherMarvelHero name = \(anotherMarvelHero.name)") //anotherMarvelHero name = The Hulk

에엥? hero를 anotherMarvelHero에 할당했는데, 왜 두 변수 다 name 속성이 The Hulk일까요?

class는 참조타입(reference type)이기 때문이에요.

"참조 타입"은 값을 복사하는 게 아니라 "참조"를 복사해요. 그래서 참조 타입을 복사하는 행위는 실제 복사가 아니라 새로운 참조를 만들어 내는 것이라고 생각하면 됩니다.

 

그래서 hero도 anotherMarvelHero도 모두 같은 객체를 가리키는 것이고, 그 놈을 바꾼다고 해도 그걸 가리키는 놈들이 다른 곳을 가리키는 것은 아니니, 같이 값이 바뀌겠져?

 

 

그런데 우리가 하나의 객체에 대한 "참조"를 2개, 3개 계속 늘려다가 보면 어떤 참조가 객체를 바꿨는지 알 수 있을까요? hero에서 바꿨는지, anotherMarvelHero에서 바꿨는지, 33번째 hero가 바꿨는지 알 수 있을까요? 참조가 많아질수록 점점 더 혼동에 빠지겠져?

 

 


2. struct vs. class 인스턴스 상수/변수

class에는 immutablility와 관련된 문제도 있습니당.

(1) class일 때, 변수 vs 상수

위와 class는 동일하구요.

class ClassHero {
    var name: String
    var universe: String
    
    init(name: String, universe: String) {
        self.name = name
        self.universe = universe
    }
}

 

이번엔 상수로 class의 인스턴스를 찍어내볼게요.

let hero = ClassHero(name: "Iron Man", universe: "Marvel")

상수 hero를 바꿔볼게요. 가능할까요? 원래 상수라면 불가능하겠져?

에엥? 상수가 바뀌네여? 왜 일까요?

class를 선언한 곳으로 가보면 ClassHero 내의 name 속성이 변수로 선언되어 있기 때문에 가능해요.

 

 

그 대신 hero 자체는 상수로 선언되었기 때문에 다른 값을 부여하는 것 안된다고 에러가 뜹니다.

 

구조체는 어떨까요?

(2) struct일 때, 변수 vs 상수

휴우~ 구조체는 우리가 아는 그대로군요. 상수로 선언하니 값을 바꿀 수 없습니다.

구조체를 선언할 때 속성이 변수라도 구조체의 인스턴스 자체가 상수라면 값을 변경할 수 없습니당.

해당 인스턴스에 다른 값을 부여하는 것도 당연히 안되구여!

 

 


 

Udemy강의를 통해 쌤이 들어준 예시가 좀 이해하기가 쉬어서 말해보자면,

예를들어 팀에서 프레젠테이션을 해야 한다고 가정할게요.

 

이때 제가 발표 자료에 수정할 게 있어서 복사한 다음에 집에 가서 작업하는 건 바로 구조체(값 타입)과 유사합니당. 우리가 평소에 사용하는 복사의 개념과 유사해요. 복사본마다 새로운 작업을 할 수 있져.

 

그러나 모든 팀원들이 유일하게 하나의 발표자료만 프린트하여 거기에 줄고 긋고, 동그라미도 치고, 별표도 하는 건 클래스(참조 타입)과 유사해요. 똑같은 객체에 작업을 하는 거죠.

 


구조체의 경우,

- 더 간단

- 더 빠름

- 값의 복사

- 진정한 불변성

- 메모리 누수 없음

- 쓰레드세이프

 

 

클래스의 경우,

- 상속 가능

- objective-C 코드와 작업 가능

 

왠만하면 구조체를 먼저 쓰도록 노력하고, 상속과 같은 클래스가 필요한 경우에만 클래스를 사용하면 될 것 같아요!

그래야 에러도 적고, 우리가 예측도 가능하니까요!!

 


 

뭔가 이 Hero 예가 이해가 잘 가는 것 같아 강의를 듣고 주절주절 정리해보았는데요!

혹시 잘못된 게 있다면 언제든지 알려주십셔 슨배님덜!!

'swift' 카테고리의 다른 글

[swift] 접근제어(Access Control)  (0) 2022.03.23
[swift] Tuple  (0) 2022.03.22
[swift] 계산 속성(computed property)  (0) 2022.03.21
[swift] Singleton 알아보기  (0) 2022.03.14
[swift] Result Type 알아보기  (0) 2022.02.03
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크