프로그래밍미드 iOS 개발자

스위프트 구조체에서 mutating 함수의 메커니즘은 어떻게 작동하며, 이것이 값 타입의 상태를 변경하는 데 왜 필요한가요? mutating 메서드는 어떤 제한이 있나요?

Hintsage AI 어시스턴트로 면접 통과

답변.

스위프트에서 구조체(struct)는 기본적으로 값 타입(value type)입니다: 구조체 인스턴스를 복사할 때 독립적인 복사본이 생성됩니다. 그러나 클래스와 달리, 구조체의 메서드는 컴파일러의 직접적인 허가 없이 self와 그 속성을 변경할 수 없습니다. 초기 C 및 C++ 버전에서 구조체는 항상 변경 가능했으며, 이로 인해 예기치 않은 부작용이 발생했습니다. 스위프트는 상태를 변경하는 메서드를 명시적으로 mutating 키워드로 표시하도록 요구하여 안전성을 높였습니다.

문제가 발생하는 것은, 구조체의 속성을 변경하기 위한 메서드가 일반적인 것으로 선언되었을 경우, 컴파일러가 이를 허락하지 않게 됩니다. mutating 없이는 self 또는 그 속성을 변경할 수 없습니다.

해결 방법은 이러한 메서드를 mutating 키워드를 사용하여 선언하는 것으로, 이는 컴파일러에게 self와 내장 속성의 변경을 허락하도록 신호를 보냅니다.

코드 예:

struct Counter { var value = 0 mutating func increment() { value += 1 } // 이 메서드는 mutating을 제거하면 컴파일되지 않습니다. } var counter = Counter() counter.increment() // value는 이제 1이 되었습니다.

주요 특징:

  • mutating이 있는 메서드만 self와 그 속성을 변경할 수 있습니다.
  • let으로 선언된 인스턴스에서는 mutating 메서드를 호출할 수 없습니다.
  • 구조체 내에서 self는 mutating 메서드 내에서 완전히 교체될 수 있습니다.

속임수 질문.

1. let으로 선언된 구조체에서 mutating 메서드를 호출할 수 있나요?

아니요, 불가능합니다. const let 값의 구조체는 mutating 메서드가 있더라도 변경될 수 없습니다.

let counter = Counter() counter.increment() // 컴파일 오류

2. 구조체 내 클래스의 내장 속성은 mutating 메서드 내에서 변경될 수 있나요?

네, 구조체 속성이 레퍼런스 타입(예: 클래스)이라면 그 내부 속성은 mutating 없이도 변경할 수 있지만, 구조체 전체는 mutating을 통해서만 변경할 수 있습니다.

class State { var value = 0 } struct Wrapper { var state = State() mutating func change() { state.value += 1 } }

3. mutating 없이 메서드 내에서 computed property만 변경할 수 있나요?

아니요. computed property에 set이 있으면 메서드 내에서 그 값을 변경하는 것은 여전히 mutating이 필요합니다.

일반적인 오류 및 안티 패턴

  • 메서드를 mutating으로 선언하는 것을 잊어버려 속성 변경이 컴파일되지 않음.
  • 상태 변경이 자주 필요한 경우 구조체를 사용하는 것 — 이럴 때는 클래스가 더 좋습니다.
  • 변경 시 구조체 복사의 특성을 무시함.

실제 사례

부정적인 케이스

프로젝트에 간단한 카운터가 구현되었지만, 개발자가 메서드를 mutating으로 표시하는 것을 잊었습니다. 값이 변하지 않아 테스트가 실패합니다.

장점:

  • 기능이 빠르게 구현되었습니다.

단점:

  • 개발자는 오류를 이해하지 못해 원인 파악에 시간이 소요됩니다.
  • 변경 사항이 기록되지 않아 코드에 혼란이 생깁니다.

긍정적인 케이스

구조체의 메서드가 mutating으로 표시되어 테스트가 통과하고 변경 사항이 올바르게 업데이트됩니다. 코드가 팀의 모든 구성원이 이해할 수 있습니다.

장점:

  • 엄격한 타입화와 예측 가능한 동작.
  • 높은 내결함성.

단점:

  • 시그니처에서 mutating을 기억해야 하는 추가적인 의무가 생깁니다.