궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFT/Grammar

Swift : 기초문법 [메서드 #2 mutating]

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

본 게시글은 yagom님과Zedd0202님의 게시글을 참고하여 작성되었습니다.

 

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 메서드의 selfBodyStruct가 되고, 매개변수의 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: 문제를 풀려면 이곳을 클릭해주세요.

 

 

읽어주셔서 감사합니다🤟

 

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.