struct를 사용하다보면, 내부에 정의된 프로퍼티 값을 변경하는 function을 정의하는 것은 기본적으로 제한되어 있습니다. 프로퍼티가 var여도 마찬가지 입니다.
struct MyStruct {
var name: String {
willSet {
print(newValue)
}
}
func changeName(_ newName: String) {
self.name = newName //error: cannot assign to property: 'self' is immutable
}
}
이는 struct의 기본적인 특징을 알면 왜 그런지 이해하기 쉽습니다. struct는 class와 다르게 struct가 constant로 정의된 경우에 내부 프로퍼티가 var일지라도 변경이 불가능한 특징이 있습니다.
struct MyStruct {
var name: String {
willSet {
print(newValue)
}
}
}
let st = MyStruct(name: "G")
st.name = "H" // error: cannot assign to property: 'st' is a 'let' constant
MyStruct 인스턴스인 st가 constant이기 때문에 name 프로퍼티가 var 일지라도 값 변경이 불가능합니다. 반면에 class는 이런 경우에 프로퍼티 값 변경이 가능합니다.
만일 var st = MyStruct(name: "G") 였다면 name 프로퍼티 값 변경이 가능했겠죠.
struct는 let으로 선언되느냐 var로 선언되느냐에 따라 내부 프로퍼티 값 변경 가능 여부에 차이가 생긴다는 것을 알 수가 있습니다. 그런데 Swift는 제가 struct를 만들 때 var로 선언을 할 지 let으로 선언을 할 지 알 수가 없습니다. 그렇기 때문에 Swift는 프로퍼티의 값을 변경하는 method를 허용하지 않는 것입니다.
만약에 struct를 let으로 선언을 했는데 (그러면 프로퍼티 값 변경이 제한되겠죠?) 프로퍼티 값을 변경하는 메서드가 있어서 외부에서 해당 메서드를 호출하면, struct를 let으로 선언한 의미가 없어지게 되는 것입니다. 그렇기 때문에 애초에 그런 일이 일어나지 못하도록 하는 것입니다.
만일 struct 내부 프로퍼티의 값을 변경하는 메서드를 정의하고 싶다면 func 앞에 `mutating`이라는 키워드를 붙여주면 됩니다.
struct MyStruct {
var name: String {
willSet {
print(newValue)
}
}
mutating func changeName(_ newName: String) {
self.name = newName
}
}
var st = MyStruct(name: "G") // let으로 선언되면 changeName(_:) 호출이 불가능 합니다!
st.changeName("IJ") // Prints "IJ"
하지만 역시나 struct를 var로 선언해주어야 프로퍼티 값을 변경하는 메서드 호출이 가능합니다. 이는 앞에서 말한 struct의 특징의 일관성을 위한 것입니다.
정리하자면
1. Swift의 struct는 let으로 선언된 경우 내부 프로퍼티가 변수일지라도 값 변경이 불가능하다.
2. struct 메서드는 내부 프로퍼티 값을 변경하는 로직을 작성할 수 없게 되어 있다.
3. 만일 프로퍼티 값을 변경하는 로직을 넣고 싶다면 func 앞에 mutating을 붙여주어야 한다.
4. var로 선언된 struct 인스턴스만 mutating 메서드를 호출할 수 있다.
참고자료
https://www.hackingwithswift.com/sixty/7/5/mutating-methods
'Swfit' 카테고리의 다른 글
Structure의 immutability (2) | 2024.04.21 |
---|---|
super.viewDidLoad를 호출하는 이유 (1) | 2024.03.21 |
some (opaque type)으로 type 숨기기 (0) | 2024.01.23 |
some에 대해 알아보기 (any와 비교) (2) | 2024.01.22 |
WidgetKit - Timeline Provider (1) | 2024.01.19 |