[iOS / Swift] Swift 문법을 알아보자! - 9편 : 클래스와 구조체의 공통점과 차이점

프린스송·2021년 5월 26일
1

Swift 문법

목록 보기
9/21
post-thumbnail
post-custom-banner

저저번 포스트와 저번 포스트에서는 클래스와 구조체에 대해 포스팅을 해보았습니다. 이 둘은 뭔가 비슷하면서도 다른 느낌을 주었는데 둘은 무슨 차이가 있을까요? 그리고 어떤 상황에서 클래스를 써야하고 구조체를 써야하는 것일까요..? 이번 시간에는 둘의 공통점과 차이점, 무엇을 언제 써야할지에 대해 포스팅을 해보겠습니다.


클래스와 구조체의 공통점

클래스와 구조체의 공통점을 정리해보겠습니다.

  • 여러 변수(속성)와 함수(메소드)를 담을 수 있는 하나의 집합.
  • 데이터를 용도에 맞게 묶어서 사용할때 편리하고 가독성을 높여줌.
  • 초기화를 정의하여 여러 매개변수에 대해 다양한 인스턴스를 생성 가능.
  • 기본적인 구현을 넘어선 기능을 확장시킬 수 있도록 확장이 가능.
  • 점(.)을 사용하여 인스턴스의 속성과 메소드에 접근할 수 있음.
  • 인스턴스 생성이 가능하고 생성 방법이 같음.
  • 특정 종류의 표준 기능을 제공하는 프로토콜을 사용 가능.
  • 새로운 데이터 타입을 만들어 주는 것.

클래스와 구조체의 차이점

그렇다면 이번에는 클래스와 구조체의 차이점에 대해 정리를 해보겠습니다.

  • 구조체에는 init()메소드 없이 자동으로 초기화 함수를 만들어 줌.
  • 클래스에서는 상속이 가능하지만 구조체는 불가능.
  • 구조체는 값 타입이지만 클래스는 참조 타입.
  • 타입캐스팅은 클래스의 인스턴스에만 허용.
  • 디이니셜라이저는 클래스의 인스턴스에만 활용 가능.
  • 참조 횟수 계산(Reference Counting)은 클래스의 인스턴스에만 적용.

차이점은 이러한 것들이 있습니다. 그러므로 클래스와 구조체는 각자 사용할 목적에 잘 선택을 해서 사용을 해야합니다!. 나중에 클래스와 구조체를 어느 곳에서 사용해야되고 각각의 사용되야 할 타이밍과 선택에 대해 공부를 많이 해야될 것 같습니다. 또한 타입캐스팅, 디이니셜라이저, 참조 횟수 계산 이런것들은 처음 듣는 단어들이네요.. 나중에 꼭 공부를 하고 넘어가야 할 것 같습니다.


값 타입과 참조 타입 (Reference Types)

값 타입은 상수나 변수에 할당하거나 함수에 넘겨질 때 복사가 됩니다. 값 타입과는 다르게 참조 타입은 변수나 상수에 할당하거나 함수에 넘길 때 복사하지 않습니다. 복사 대신에 기존에 같은 인스턴스에 참조가 사용됩니다. 즉 값이 복사되는 것이 아니라 메모리를 참조하는 것입니다!

  • 구조체는 값 타입
  • 클래스는 참조 타입

값 타입과 참조 타입은 구조체와 클래스를 구분하는 가장 큰 차이점 입니다. 하지만 위의 문장만으로는 무슨 소리인지 잘 모르겠습니다. 그래서 간단한 코드를 짜서 확인을 해보겠습니다.

struct A { //구조체 (상속이 안됨)
    var a = 10
}

class B { //클래스 (상속이 됨)
    var a = 10
}

var str_1: A = A() //값을 복사
var cls_1: B = B() //값을 참조

var str_2 = str_1
var cls_2 = cls_1

str_1.a = 20
cls_1.a = 20

print("\(str_2.a) \(cls_2.a)") 

구조체 A와 클래스 B를 선언한 후 각각에게 _1의 인스턴스를 선언해주었습니다. 그리고 _1의 인스턴스를 _2에 복사를 한 후 _1의 인스턴스의 속성 a의 값을 20으로 바꾸었습니다. 그런 후 _2의 a속성을 출력해 본다면 어떤 결과가 나올까요? 결과를 먼저 확인해 보겠습니다.
구조체의 결과는 그대로 10이 나왔고 클래스에서는 바뀐 20이 나왔습니다. 여기서 알 수 있는 사실은 위에서 언급해드린 것처럼 구조체는 복사하는 값 타입이고 클래스는 참조하는 참조 타입입니다. 즉, 구조체는 그저 복사를 하여 _1과 _2의 관계는 참조되지 않고 각각의 개별의 관계입니다! 하지만 클래스에서는 서로 참조하는 관계를 가지므로 _1과 _2는 참조관계가 되어 서로에게 영향을 주게 되는 것이지요!

만약 이런 값 타입과 참조 타입을 충분히 숙지하지 않고 클래스나 구조체를 사용했었더라면 미숙한 사용은 물론 결과에도 엄청난 영향을 미쳤을 것입니다.


어떤 것을 선택해야 할까?

구조체 인스턴스는 값을 항상 넘기며, 클래스 인스턴스는 항상 참조를 넘겨줌. 이 의미는 서로 다른 작업의 종류에 적합하다는 의미입니다. 프로젝트에 필요한 데이터 구조와 기능을 고려하여, 각각의 데이터는 클래스나 구조체로 정의하도록 구성해야 합니다.

애플에서는 다음 조건 중 하나 이상에 해당하면 구조체를 사용하는 것을 권장한다고 합니다.
1. 구조체의 최우선 목표는 몇몇 단순 데이터 값을 캡슐화 하는 경우
2. 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
3. 구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
4. 다른 기존 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때
Swift 언어 가이드


오늘은 클래스와 구조체의 공통점과 차이점에 대해서 살펴보았습니다. 워낙 비슷한 친구들이라 사용할때 조금은 헷갈릴 수 있겠지만 꼭 잘 살펴서 알맞게 사용을 해야겠군요! 그럼 오늘도 수고 많으셨습니다.

profile
[iOS / Swift] [React Native]
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 12월 2일

값 타입과 참조 타입이라고도 부르는군요 저는 얕은 복사 깊은 복사로만 생각했는데

답글 달기