[Swift] 8. 구조체와 클래스의 차이

Hoojeong Kim·2022년 3월 5일
0

Swift Base

목록 보기
10/22
post-thumbnail

구조체와 클래스

이전 포스팅에서 봤듯이, 구조체와 클래스는 같은 점이 많다. 그래서 이번에는 구조체와 클래스의 차이에 대해 알아보고자 한다.

구조체와 클래스 공통점

  • 값을 저장하기 위해 프로퍼티를 정의할 수 있다.
  • 기능 실행을 위해 메서드를 정의할 수 있다.
  • 서브스크립트 문법을 통해 구조체 또는 클래스가 갖는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있다.
  • 초기화될 때의 상태를 지정하기 위해 이니셜라이저(init)를 정의할 수 있다.
  • 초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있다.
  • 특정 기능을 실행하기 위해 특정 프로토콜을 준수할 수 있다.

구조체와 클래스 차이점

구조체

  • 값 타입이다.
  • 구조체 변수를 새로운 변수에 할당할 때마다 새로운 구조체가 할당된다.
  • 같은 구조체를 여러 개의 변수에 할당한 뒤 값을 변경해도 다른 변수에 영향을 미치지 않는다.

클래스

  • 참조 타입이다.
  • ARC로 메모리를 관리한다.
  • 상속이 가능하다.
  • 타입 캐스팅을 통해 런타임에서 클래스 인스턴스의 타입을 확인할 수 있다.
  • deinit를 사용하여 클래스 인스턴스의 메모리 할당을 해제할 수 있다.
  • 같은 클래스 인스턴스를 여러 개의 변수에 할당한 뒤 값을 변경 시키면 모든 변수에 영향을 준다.

구조체와 클래스는 위와 같은 차이점이 존재한다. 여러 차이점 중 가장 큰 것이 바로 값 타입과 참조 타입이다.

값 타입과 참조 타입

쉽게 말해, 값 타입과 참조 타입은 다음과 같다.

값 타입 : 값 자체를 복사한다.
참조 타입 : 메모리를 복사한다.

이해를 돕기 위해 다음 코드를 살펴보자.

struct SomeStruct {
	var count: Int = 0
    
    func printCount(){
    	print(count)
    }
}

class SomeClass {
	var count: Int = 0
    
    func printCount(){
    	print(count)
    }
}

위와 같이 구조체와 클래스를 정의한 뒤, 각각 3개의 인스턴스를 생성해 값을 바꿔보자.

먼저 구조체이다.

var struct1 = SomeStruct()
var struct2 = struct1
var struct3 = struct1

struct2.count = 2
struct3.count = 3

struct1.printCount()
struct2.printCount()
struct3.printCount()
0
2
3

결과를 보면 struct1, 2, 3 모두 count의 값이 다르게 출력되었다.
바로 구조체가 값 타입이기 때문이다. 같은 구조체의 인스턴스를 생성하더라도 매번 새로운 메모리가 할당된다.

때문에 프로퍼티의 값을 아무리 변경해도 다른 인스턴스에는 영향을 미치지 않는다.


이때 만약 인스턴스를 상수로 생성한다면 어떻게 될까??
let struct4 = SomeStruct()

struct4.count = 0
struct4.printCount()

위 코드를 실행하면 아래와 같은 에러가 발생한다.
Cannot assign to property: 'struct4' is a 'let' constant

에러를 보면 struct4가 상수이기 때문에 그렇다는 것을 알 수 있다. 구조체는 값 타입이기 때문에 상수로 인스턴스를 생성하면 구조체 내부에 있던 변수가 모두 상수로 바뀌게 된다.
이러한 이유로 상수로 인스턴스를 생성하면 내부 프로퍼티의 값을 변경할 수 없다.


다음은 클래스이다.

var class1 = SomeClass()
var class2 = class1
var class3 = class1

class2.count = 2
class3.count = 3

class1.printCount()
class2.printCount()
class3.printCount()
3
3
3

결과를 보면 class1, 2, 3 모두 count의 값이 3으로 출력되었다. 앞에서 클래스는 참조 타입이라고 했는데, 참조 타입은 인스턴스를 생성할 때 주소를 복사한다.

즉, 같은 클래스의 인스턴스를 여러 개 생성하면 모든 인스턴스의 프로퍼티가 같은 주소를 갖는 것이다. 때문에 하나의 인스턴스에서 프로퍼티의 값을 변경하면 다른 인스턴스에도 영향을 미친다.


구조체와 마찬가지로 인스턴스를 상수로 생성해보자.
let class4 = SomeClass()

struct4.count = 0
class4.printCount()
0

이번에는 구조체와 달리 값이 정상적으로 변경되고 출력된 것을 알 수 있다. 바로 클래스가 참조 타입이기 때문이다.

그렇기 때문에 클래스 인스턴스를 상수로 선언하더라도, 클래스 내부의 인스턴스는 변수인 본모습을 유지한다.

profile
나 애기 개발자 👶🏻

0개의 댓글