Mutating 메서드
구조체 또는 열거형의 인스턴스가 상수 let
으로 생성된 경우 해당 속성을 변경할 수 없다. 구조체를 만들 때 Swift가 상수 또는 변수와 함께 사용할지 여부를 알지 못하므로 기본적으로 안전한 접근 방식을 취하게 된다.
Swift는 특별히 요청하지 않는 한 속성을 변경하는 메서드를 허용하지 않는다. 즉, 값 타입의 속성은 기본적으로 인스턴스 메서드 내에서 수정할 수 없다는 뜻이다.
만약 구조체 내부 속성 즉, 값 타입의 속성을 수정하려면 인스턴스 메서드에서 mutating
키워드를 사용해야 수정이 가능하다.
struct Person {
var name: String
mutating func makeAnonymous() {
name = "Anonymous"
}
}
속성을 변경하기 때문에 Swift는 변수인 Person
인스턴스에서만 해당 메서드가 호출되도록 허용하게 된다.
var person = Person(name: "Ed")
person.makeAnonymous()
인스턴스 메서드에서 나왔던 self
프로퍼티를 사용해보자면, 일단 class는 참조 타입이므로 속성을 변경할 수 있지만 구조체, 열거형은 값 타입이므로 속성을 변경하려면 mutating
키워드를 사용해야 하는데 아래 코드를 먼저 살펴보려 한다.
struct BodyStruct {
var weight: Double = 0.0
func chagedWeight(to weight: Double) {
self.weight += weight
}
}
var myWeight = BodyStruct(weight: 60.5)
myWeight.chagedWeight(to: 10.2)
print(myWeight)
결론부터 말하자면 위 코드는 잘못된 코드이다. 왜냐하면 저장 프로퍼티의 weight
속성이 changedWeight
메서드에서 변경되려고 하는데 구조체는 인스턴스 메서드 내에서 값을 변경하는 것을 허용하지 않는다.
이때 필요한것이 mutating
키워드
struct BodyStruct {
var weight: Double = 0.0
mutating func changedWeight(to weight: Double) {
self.weight += weight
}
}
var myWeight = BodyStruct(weight: 60.5)
myWeight.changedWeight(to: 10.2)
print(myWeight) //70.7
이렇게 mutating
키워드를 사용해서 해당 프로퍼티를 수정 가능하게 해 줬다.
mutating
메소드는 암시적 self
프로퍼티에 완전히 새로운 인스턴스를 할당할 수 도 있다.
struct BodyStruct {
var weight: Double = 0.0
mutating func changedWeight(to weight: Double) {
self = BodyStruct(weight: self.weight + weight)
}
}
var myWeight = BodyStruct(weight: 60.5)
myWeight.changedWeight(to: 10.2)
print(myWeight) //70.7
이 새로운 코드와 위에 코드는 완벽히 동일하다는것을 확인할 수 있다. changedWeight
메서드의 self
는 BodyStruct
가 되고, 매개변수의 self.weight
는 저장 프로퍼티를 의미한다.
배열에서도 구조체와 동일하게 작용한다.
enum YesOrNoEnum {
case yes, no
mutating func answer() {
self = self == .yes ? .no : .yes
}
}
var myAnswer: YesOrNoEnum = YesOrNoEnum.yes
myAnswer.answer() //no
enum TriStateSwitch {
case off, low, high
mutating func next() {
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
var ovenLight = TriStateSwitch.off
ovenLight.next() //low
//off -> low 로 변경됨
ovenLight.next() //hight
//hight -> off 로 변경됨
예시
struct Diary {
var entries: String
mutating func add(entry: String) {
entries += "\(entry)"
}
}
struct BankAccount {
var balance: Int
mutating func donateToCharity(amount: Int) {
balance -= amount
}
}
struct Delorean {
var speed = 0
mutating func accelerate() {
speed += 1
if speed == 88 {
travelThroughTime()
}
}
func travelThroughTime() {
print("Where we're going we don't need roads.")
}
}
mutating TEST: 문제를 풀려면 이곳을 클릭해주세요.
읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift : 기초문법 [인스턴스 #1 이니셜라이저, 매개변수) (0) | 2022.01.15 |
---|---|
Swift : 기초문법 [메서드 #3 타입 메서드] (0) | 2022.01.14 |
Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] (0) | 2022.01.13 |
Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] (0) | 2022.01.10 |
Swift : 기초문법 [프로퍼티#4 - 타입 프로퍼티] (0) | 2022.01.10 |