Swift에서는 상수와 변수를 제공하고 있습니다.
[상수]
let 키워드를 사용하여 값을 저장할 수 있지만, 한 번 저장된 값을 다른 값으로 변경할 수 없습니다.
<상수 사용 예시>
let str = "A"
<상수로 선언된 값을 변경하려고 할 때>
str = "B" // cannot assign to value: 'str' is a 'let' constant
상수로 선언된 "str"을 값으로 변경하려고 하면 에러가 발생합니다. 값을 변경할 수 없는 상수 "str"의 값을 변경하려고 하기 때문입니다.
값을 변경하고 싶을 때에는 "str"상수를 변수로 변경해야 합니다.
[변수]
var 키워드를 사용하여 값을 저장하고, 다른 값으로 변경이 가능합니다.
<변수 사용 예시>
var str = "A"
<변수로 선언된 값을 변경하려고 할 때>
print(str) // "A"
str = "B"
print(str) // "B"
변수는 값을 변경할 수 있기 때문에 기존의 값("A")를 변경하려고 하는 값("B")로 변경이 되는 것을 볼 수 있습니다.
기존에는 위처럼 "상수는 값을 변경할 수 없고, 변수는 값을 변경할 수 있다" 라고만 막연하게 학습하고 넘어갔습니다.최근에 변수와 상수에 좀 더 공부하면서 객체의 입장에서 값이 변경될 수 없다는 것과 값이 변경이 된다는 것에 대한 생각을 가지게 되었습니다.
첫 번째로는 객체의 값을 변경할 수 있다는 것은 기존의 객체 인스턴스를 다른 인스턴스로 변경이 가능하다는 의미가 될 수도 있습니다.
구조체와 클래스의 경우를 비교하며 예시를 들어보겠습니다.
<구조체>
struct Person {
var name: String
}
let person = Person(name: "James")
person = Person(name: "Mike") // cannot assign to value: 'person' is a 'let' constant
위에서는 구조체 Person 객체를 상수로 선언하였습니다. 기존 인스턴스를 다른 인스턴스로 변경하려면 에러가 발생했습니다. 왜냐하면 기존 인스턴스가 상수로 선언을 하였기 때문에 값을 바꿀 수 없기 때문입니다.
그렇다면 구조체 Person 객체를 변수로 선언하면 기존 인스턴스를 다른 인스턴스로 변경할 수 있을까요?
struct Person {
var name: String
}
var person = Person(name: "James")
person = Person(name: "Mike")
결론부터 말하자면 다른 인스턴스로 변경이 가능합니다. var는 변수로서 값을 변경할 수 있기 때문에 기존 인스턴스에서 새로운 인스턴스로 변경이 가능하게 됩니다.
<클래스>
class Person {
var name: String
init(name: String) {
self.name = name
}
}
let person = Person(name: "James")
person = Person(name: "Mike") // cannot assign to value: 'person' is a 'let' constant
위에서는 클래스 Person 객체를 상수로 선언하였습니다. 기존 인스턴스를 다른 인스턴스로 변경하려면 에러가 발생했습니다. 왜냐하면 기존 인스턴스가 상수로 선언을 하였기 때문에 값을 바꿀 수 없기 때문입니다.
그렇다면 클래스 Person 객체를 변수로 선언하면 기존 인스턴스를 다른 인스턴스로 변경할 수 있을까요?
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person = Person(name: "James")
person = Person(name: "Mike")
결론부터 말하자면 다른 인스턴스로 변경이 가능합니다. var는 변수로서 값을 변경할 수 있기 때문에 기존 인스턴스에서 새로운 인스턴스로 변경이 가능하게 됩니다.
결론적으로 구조체와 클래스에서는 let으로 선언이 되면 다른 인스턴스로 변경을 할 수 없고, var로 선언이 되면 다른 인스턴스로 변경을 할 수 있다는 사실을 알 수 있습니다.
두 번째로는 객체의 속성을 변경할 수 있다는 의미가 될 수도 있습니다.
마찬가지로 구조체와 클래스의 경우를 비교하며 예시를 들어보겠습니다.
<구조체>
struct Person {
var name: String
}
let person = Person(name: "James")
person.name = "Mike" // cannot assign to property: 'person' is a 'let' constant
위에서는 구조체 Person 객체를 상수로 선언하였습니다. 인스턴스의 객체의 속성을 변경하려고 할 때 에러가 발생했습니다. 속성 값을 변경하려고 하는 행위 자체가 객체의 값을 변경하려고 시도하는 것이기 때문에 상수로 선언이 되어있으면 속성 값을 변경할 수 없습니다.
그렇다면 구조체 Person 객체를 변수로 선언하면 인스턴스의 속성을 변경할 수 있을까요?
struct Person {
var name: String
}
var person = Person(name: "James")
person.name = "Mike"
결론부터 말하자면 인스턴스의 속성을 변경할 수 있습니다. var는 변수로서 값을 변경할 수 있기 때문에 속성을 변경할 수 있습니다. 대신, 속성을 변경하려면 변수로 선언이 되어있어야 합니다.
<클래스>
class Person {
var name: String
init(name: String) {
self.name = name
}
}
let person = Person(name: "James")
person.name = "Mike"
위에서는 클래스 Person 객체를 상수로 선언하였습니다. 상수로 선언이 되어 속성을 변경할 수 없다고 생각하는데 속성을 변경할 수 있습니다. 이유는 클래스 객체를 상수에 할당할 때, 클래스 객체 자체의 값이 아니라 할당된 메모리 주소 값을 저장하므로 Person 객체의 인스턴스의 주소를 참조하여 속성을 변경할 수 있습니다.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person = Person(name: "James")
person.name = "Mike"
마찬가지로 클래스 Person 객체를 변수로 선언이 되어도 속성값을 변경할 수 있습니다.
결론적으로 구조체에서는 let으로 선언이 되어있으면 해당 속성을 변경하려고 할 때, 값을 변경하려는 행위로 인식이 되기 때문에 속성을 변경할 수 없고, var로 선언이 되어야만 속성을 변경할 수 있습니다. 하지만, 클래스에서는 let 또는 var로 선언이 되면 클래스 객체를 할당하는 메모리 주소를 저장하기 때문에 주소를 참조하여 속성을 변경할 수 있습니다.
지금까지 Swift의 상수와 변수에 대해서 알아보았습니다.
'Swift' 카테고리의 다른 글
[Swift] 스위프트 메모리 관리 (2) | 2023.10.26 |
---|---|
[Swift] deinitializer 활용 (1) | 2023.10.26 |
[Swift] 클로저의 Escaping과 Capture List (0) | 2023.10.24 |