Swift

swift: 구조체와 클래스의 차이

소재훈 2022. 1. 21. 19:35

구조체와 클래스는 같은 점도 있지만 다른 점도 있다. 같은 점은 다음과 같다.

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

다른 점은 다음과 같다.

  • 구조체는 상속할 수 없다.
  • 타입 캐스팅은 클래스의 인스턴스에만 허용된다.
  • 디이니셜 라이저는 클래스의 인스턴스에만 활용할 수 있다.
  • 참조 횟수 계산(Reference Counting)은 클래스의 인스턴스에만 적용된다.

구조체와 클래스를 구분 짓는 가장 큰 차이점은 구조체는 값 타입, 클래스는 참조 타입이라는 것이다.

 

값 타입과 참조 타입의 가장 큰 차이점은 무엇이 전달되느냐 이다.  값 타입은 전달될 값이 복사되어 전달되지만, 참조 타입은 값을 복사하지 않고 참조(주소)가 전달된다.

struct BasicInformation {
    let name: String
    var age: Int
}

var jaehoonInfo: BasicInformation = BasicInformation(name: "Jaehoon", age: 24)
jaehoonInfo.age = 25

var friendInfo: BasicInformation = jaehoonInfo

print("jaehoon's age: \(jaehoonInfo.age)") // 25
print("friend's age: \(friendInfo.age)") // 25

friendInfo.age = 26
print("jaehoon's age: \(jaehoonInfo.age)") // 25

// friendInfo는 jaehoonInfo의 값을 복사한 것이기 때문에 별개의 값을 가진다.

class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
}

var jaehoon: Person = Person()
var friend: Person = jaehoon

print("jaehoon's height: \(jaehoon.height)") // 0.0
print("friend's height: \(friend.height)") // 0.0

friend.height = 165.2
print("jaehoon's height: \(jaehoon.height)") // 165.2

// jaehoon이 참조하는 곳과 friend가 참조하는 곳이 같음을 알 수 있다.

 

값 타입의 데이터를 함수의 전달 인자로 전달하면 메모리에 전달 인자를 위한 인스턴스가 새로 생성된다.

참조 타입의 데이터는 전달인자로 전달할 때 기존 인스턴스의 참조를 전달하므로 새로운 인스턴스가 아닌 기존의 인스턴스 참조를 전달한다.

 

클래스의 인스턴스끼리 같은 참조인지를 확인할 때는 식별 연산자(Identity Operators, ===)를 사용한다. 

var eunsung: Person = Person()
let friend: Person = eunsung
let anotherFriend: Person = Person()

print(eunsung === friend) // true
print(eunsung === anotherFriend) // false
print(friend !== anotherFriend) // false

 

스위프트의 모든 기본 타입(Bool, Int, String, Array, Dictionary, Set,...)은 구조체로 구현되어 있다. 기본 데이터 타입은 모두 값 타입이라는 의미이다. 전달인자를 통해서 데이터를 전달하면 모두 값이 복사되어 전달될 뿐 함수 내부에서 아무리 값을 변경해도 기존의 변수나 상수에 영향을 미치지 못한다. 

 

애플의 가이드라인에서는 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하는 것을 권장한다.

  • 연관된 간단한 값의 집합을 캡슐화 하는 것만이 목적일 때
  • 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
  • 구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
  • 다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때

'Swift' 카테고리의 다른 글

swift: 연산 프로퍼티  (0) 2022.01.21
swift: 저장 프로퍼티  (0) 2022.01.21
swift: 클래스  (0) 2022.01.21
swift: 구조체  (0) 2022.01.21
swift: 옵셔널(Optional)  (0) 2022.01.21