프로그래밍iOS 개발자

패턴 매칭은 Swift의 구조체와 연관 값이 있는 열거형에 대해 어떻게 작동하나요? `if case`, `guard case`, `switch`를 사용한 패턴 매칭의 차이점과 복잡한 열거형에서 case 이름과 중첩의 역할은 무엇인가요?

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

답변.

패턴 매칭은 Swift의 근본적인 특징으로, 코드를 더 안전하고 깔끔하게 만듭니다. 역사적으로 패턴 매칭은 관련 값을 포함한 열거형을 보다 표현력 있고 안전하게 다루기 위한 수단으로 발전했습니다. 다른 언어들과는 달리, Swift는 if, guard, switch 표현에서 중첩된 값을 직접 풀 수 있게 해줍니다.

문제: 비표준 열거형, 특히 중첩된 연관 값을 가진 경우에는 case 구조에서 쉽게 실수할 수 있거나 주요 switch의 제한을 과소평가할 수 있습니다. 또한 if case, guard case와 전통적인 switch 사용 간의 차이가 종종 명확하지 않습니다.

해결책: 시나리오에 따라 다른 패턴 매칭 접근 방식을 적용하고, 복잡한 중첩 구조에서는 이름을 명시적으로 지정하고 where를 사용하는 것이 좋습니다.

코드 예제:

enum NetworkState { case success(User) case failure(Error, code: Int) case loading(progress: Double) } let state = NetworkState.failure(SomeError(), code: 401) if case let .failure(error, code) = state, code == 401 { print("Unauthorized: \(error)") } guard case .success(let user) = state else { return } print(user) switch state { case .success(let user): print("Welcome, \(user.name)") case .failure(let error, let code) where code == 404: print("Not Found: \(error)") case .failure(_, let code): print("Failure with code: \(code)") case .loading(let progress): print("Progress: \(progress)") }

주요 특징:

  • 패턴 매칭은 switch, if case, guard case 및 let/var 바인딩을 통해 가능합니다.
  • where를 통해 필터링할 수 있습니다.
  • switch의 패턴 매칭은 모든 열거형 case를 명시적으로 설명할 수 있게 하여 누락된 시나리오가 없도록 보장합니다.

트릭 질문.

switch에서 모든 열거형 case를 누락하면 어떻게 되나요?

컴파일 오류(열거형이 non-optional인 경우) 또는 모든 커버리지가 고려되지 않은 경우 경고/기본 case 요구입니다. Optionals는 .some과 .none만 지정하면 충분합니다.

중첩된 열거형 및 연관 값으로 패턴 매칭을 할 수 있나요?

네. 하지만 구문이 복잡해집니다. 중첩된 값을 위해 여러 레벨을 즉시 풀 수 있습니다:

enum Outer { case inner(Inner) } enum Inner { case item(id: Int) } let e = Outer.inner(.item(id: 5)) if case let .inner(.item(id)) = e { print(id) }

패턴 매칭에서 guard case와 if case의 차이점은 무엇인가요?

guard case는 조건을 확인하고 실패 시 exit 블록(return, throw, break)을 수행합니다. 일반적으로 요구 사항에 사용되며, 일치하지 않으면 나갑니다.

if case는 함수에서 나가지 않고 단일 라인 조건 처리기에 적합한 구조입니다.

일반적인 오류 및 안티 패턴

  • switch에서 모든 열거형 case에 대한 커버리지를 누락하면 오류와 크래시가 발생합니다.
  • 중첩 값 풀기에서 이름이나 중첩 수준을 혼동할 수 있습니다.
  • .none-case를 고려하지 않고 optional 값에 대해 if/switch를 사용하는 경우 시나리오가 누락될 수 있습니다.

실생활 예제

부정적인 사례

개발자가 여러 case를 가진 열거형을 위해 switch를 사용하지만 새로운 case를 커버하지 않습니다. 코드는 컴파일되지만 새로운 시나리오는 처리되지 않으며 애플리케이션이 런타임에 크래시됩니다.

장점:

  • default를 통해 최소한의 처리기를 쉽게 추가할 수 있습니다.

단점:

  • 누락된 시나리오로 인해 원인을 추적하기 어렵습니다.
  • 새로운 case가 나타날 경우 잠재적인 크래시가 발생할 수 있습니다.

긍정적인 사례

개발자가 모든 case를 명시적으로 커버하고, 지역 필터링을 위해 where를 사용하며, 중첩된 let을 통해 중첩된 값을 풀어냅니다.

장점:

  • 완전한 타입 안전성
  • 모든 시나리오가 명시적으로 설명됩니다.

단점:

  • 때때로 과도하게 느껴질 수 있는 길고 복잡한 switch나 이중 패턴 매칭이 필요할 수 있습니다.