- swift에 대해 공부한 내용을 정리한 글입니다.
- 해당 글은 한빛미디어의 스위프트 프로그래밍 3판을 참고하여 작성했습니다.
이전 포스팅에서 봤듯이, 구조체와 클래스는 같은 점이 많다. 그래서 이번에는 구조체와 클래스의 차이에 대해 알아보고자 한다.
구조체와 클래스는 위와 같은 차이점이 존재한다. 여러 차이점 중 가장 큰 것이 바로 값 타입과 참조 타입이다.
쉽게 말해, 값 타입과 참조 타입은 다음과 같다.
값 타입 : 값 자체를 복사한다.
참조 타입 : 메모리를 복사한다.
이해를 돕기 위해 다음 코드를 살펴보자.
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
이번에는 구조체와 달리 값이 정상적으로 변경되고 출력된 것을 알 수 있다. 바로 클래스가 참조 타입이기 때문이다.
그렇기 때문에 클래스 인스턴스를 상수로 선언하더라도, 클래스 내부의 인스턴스는 변수인 본모습을 유지한다.