본문 바로가기
Swift

[Swift] 상수와 변수

by giop15 2023. 10. 23.
반응형

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] 스위프트 메모리 관리  (1) 2023.10.26
[Swift] deinitializer 활용  (1) 2023.10.26
[Swift] 클로저의 Escaping과 Capture List  (0) 2023.10.24