iOS/Swift
Swift) 값 타입과 참조 타입 그리고 클래스와 구조체 (Value type & Reference type, Class & Struct)
hyunjicraft
2021. 1. 5. 19:13
값 타입과 참조 타입
값 타입
변수를 할당하면 스택 영역에 값이 저장된다.
변수를 복사한 후 복사본을 변경하더라도 원본에 영향을 주지 않는다.
힙 영역을 사용하지 않고 레퍼런스 카운팅이 필요하지 않다.
참조 타입
스택 영역에는 포인터(레퍼런스)만 할당되고 실제 데이터는 힙 영역에서 할당된다.
변수를 복사하더라도 하나의 값을 가리키고 있기 때문에 복사본과 원본이 모두 같은 값을 갖는다.
변수를 복사하더라도 레퍼런스 카운트만 +1되고 실제 값이 복사되지는 않는다.
Swift의 Class와 Struct는 생김새와 사용법이 유사하다.
구조체는
1. 값 타입이다.
2. 상속이 불가능하다.
3. 생성자를 구현하지 않아도 default initializer를 사용할 수 있다.
struct Car {
var name : String
var color : String
}
let car1 = Car(name: "i7", color: "Black")
print(car1)
//Car(name: "i7", color: "Black")
var car2 = car1
print(car2)
//Car(name: "i7", color: "Black")
car2.name = "i9"
print(car2)
print(car1)
//Car(name: "i9", color: "Black")
//Car(name: "i7", color: "Black")
//car2의 프로퍼티를 변경해도 원본인 car1의 프로퍼티 값은 변경되지 않았다.
클래스는
1. 참조 타입이다.
2. 생성자를 구현해야만 사용할 수 있다.
class Student {
var name : String
var age : Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func print() {
print("name: \(name), age: \(age)")
}
//기본 print() 함수를 사용하면 주소값이 출력되기 때문에 직접 함수로 구현함.
}
let std1 = Student(name: "Peter", age: 17)
std1.print()
//name: Peter, age: 17
let std2 = std1
std2.print()
//name: Peter, age: 17
std2.name = "Ken"
std2.print()
std1.print()
//name: Ken, age: 17
//name: Ken, age: 17
//std2의 프로퍼티 값을 변경하면 원본인 std1의 프로퍼티 값도 함께 변경된다.
* Swift의 Enum, Array, String, Dictionary, Set, Tuple도 Struct와 동일한 값 타입이다
* Swift의 Function과 Closure는 Class와 동일한 참조 타입이다.
차이를 구분하지 않고 써도 무리가 없는 경우가 많지만 개념을 확실히 알고 있다면 도움이 될 것 같다.