본문 바로가기
iOS/Swift

[iOS/Swift] immutable한 구조체, mutating을 적용한다면?

by iosdevlime 2023. 3. 7.

이전에 다룬 구조체(Struct)의 주요한 특징을 기억하시나요?

 

참조 타입인 클래스(Class)와는 달리,

인스턴스 객체가 생성될 때 마다 별도의 값을 가지게 되는,

 

'값 타입(Value Type)'이란 부분이 구조체의 중요한 특징 중 하나였습니다.

 

그렇기 때문에 ~ 

클래스는 인스턴스 메서드를 활용해 내부 인스턴스 값을 변경할 수 있으나,

구조체는 '값' 자체를 복사하여 사용하므로 그렇지 못한다고 생각했지만...?

 

구조체의 성질을 '변화' 시켜서 내부 데이터 값을 수정할 수도 있습니다!

 

그 시작으로 mutableimmutable이란 용어를 짚고 넘어가보도록 하겠습니다.

 

 

 


 

 

mutable과 immutable

구조체는 상수(Constant)와 동일한 변화되지 않는(Immutable) 성질이다.

 

mutating의 사전적 의미는 다음과 같습니다. 

mutating
- '변화시키다' 혹은 '돌연변이'

 

말 그대로,

원래 그렇지 않은데 ➟ 조건에 따라 돌연변이가 되는 행위로도 해석되는데 말입니다..

 

근데, mutating이 대체 구조체와 무슨 연관이 있는걸까요?

 

 

 

mutable 하다, immutable 하다

  • Swift 문법에 대한 학습 초기, 이미 mutable과 immutable에 대한 의미를 알아보았습니다.
    • 바로 변수(var)와 상수(let)가 변화되는, 즉 'mutable'의 특징에 따라 구분됩니다.
  • 이는 참조타입인 클래스와 값 타입인 구조체 또한 동일하게 적용됩니다.
    • 클래스는 기본적으로 항상 'mutable' 하다고 볼 수 있습니다.
    • 하지만, 구조체는 default 값으로 'immutable' 규칙을 지키게 됩니다.

 

 

 

구조체의 성질변화, mutating

  • 구조체는 immutable 규칙을 지키는 동시에, mutable한 메서드를 사용할 수 있습니다.
    • 기본적으로 구조체 인스턴스 메서드에서는 내부 값(Property)를 수정할 수 없습니다.
    • 다만 'mutating' 키워드를 활용할 시 mutable한 성질을 가질 수 있습니다!
  • 다음 예시코드는 mutating 키워드를 활용한 구조체 내부의 값을 변경하는 과정입니다.
    • Animals란 구조체는 name 문자열age 정수값을 데이터로 가지고 있습니다.
    • 동물의 나이를 5살로 유지하고 싶다는 생각에, 'defaultAge'란 인스턴스 메서드를 생성합니다.
// 예제 코드 (구조체 Animals)
struct Animals {
    let name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    func defaultAge() {
        age = 5
    }
}

 

  • 하지만, immutable한 구조체의 성격에 따라 인스턴스 메서드에 아래와 같은 오류가 발생합니다.
    • 이유는 즉, initializer 시 self 키워드 자체가 상수(let)로 정의되어 있기 때문입니다.
    • 따라서 DefaultAge() 메서드는 작동할 수 없고, 앞서 언급한 mutating 키워드를 붙여야 합니다.

구조체 내부, self는 자동적으로 let으로 정의되어 있다!
구조체 내부, self는 자동적으로 let으로 정의되어 있다!

struct Animals {
    let name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    // mutating 키워드를 인스턴스 메서드 앞에 붙인다.
    mutating func defaultAge() {
        age = 5
    }
}

 

 

  • myDog 인스턴스를 생성한 후, 초기값을 부여합니다.
    • name은 'Coco', age는 10으로 설정한 이후, 내부에 위치한 defaultAge()를 호출한다면?
    • age는 5로 변경되는 동시에, mutable한 성격을 가지게 됩니다.
var myDog: Animals = Animals(name: "Coco", age: 10)
myDog.defaultAge()

print(myDog.age) // 5

 

 


 

이번 포스팅에서 다룬 mutable이란 개념은

 

추후 SwiftUI View(구조체)를 다룰 시 연계되는 내용 중 하나이므로,

반드시 숙지하고 넘어갈 필요가 있겠습니다.

 

댓글