스위프트의 패턴 매칭은 조건문 switch, 반복문 및 if case 연산자에서 값을 우아하게 추출하고 패턴과 비교할 수 있도록 합니다. 주요 특징은 값을 비교하는 것뿐만 아니라 연관된 데이터를 복잡한 구조에서 추출할 수 있는 기능입니다. 예를 들어, 연관된 값을 가진 열거형, 옵셔널 또는 튜플에서 데이터 추출이 가능합니다.
case let 연산자는 중첩된 값을 추출하는 데 자주 사용됩니다. 예를 들면:
enum Result { case success(value: Int) case failure(error: Error) } let result: Result = .success(value: 42) switch result { case .success(let value): print("Success with value \(value)") case .failure(let error): print("Failed with error: \(error)") }
컬렉션 작업 시 패턴 매칭을 적용하는 것도 편리합니다:
let items: [Result] = [.success(value: 1), .failure(error: MyError()), .success(value: 42)] for case let .success(value) in items { print("Found value: \(value)") }
모든 패턴이 작동하는 것은 아니며, 구조체나 열거형이 연관된 값 없이 작성되거나 Equatable을 지원하지 않는 경우 문제가 발생할 수 있습니다. 또한 경험이 부족한 개발자들은 enum의 모든 경우에 대한 exhaustiveness(모든 경우를 고려하는 것)를 제대로 처리하지 못할 수 있습니다.
옵셔널 값 작업 시 if let, guard let 및 if case let의 차이점은 무엇인가요? 각각의 경우 어떤 경우에 더 선호되나요?
답변:
if let과 guard let은 옵셔널에서 안전하게 값을 추출하기 위해 사용됩니다.if case let은 옵셔널뿐만 아니라 연관된 값을 가진 열거형에서도 사용 가능하여 패턴 매칭의 가능성을 확장합니다.예시:
let number: Int? = 42 if case let value? = number { print("Value is \(value)") }
value?는 nil이 아닐 경우에만 값을 추출하는 패턴입니다.
이야기
개발자가 switch에서 enum의 모든 case를 구현하지 않았습니다. enum에 새로운 case를 추가하는 것에 의해 silent-오류가 발생했으며, 이는 "신뢰성을 위해" default 분기가 추가되었기 때문입니다. 결과적으로 일부 로직이 작동하지 않게 되었고 오류는 사용자에게만 나타났습니다.
이야기
프로젝트에서
Result<T, Error>배열을 사용하며 일반적인 반복문for x in...를 통해 성공적인 값만 필터링하려고 했습니다. 이는 타입을 수동으로 체크하게 만들어 조건 오류로 인한 성공 사례가 누락되는 결과를 초래했습니다.
이야기
팀의 한 구성원이 옵셔널을 위한
if case let을 알지 못해 항상 이중 확인을 하였습니다: 먼저if number != nil을 체크한 후 "강제 추출"을 사용했습니다. 이는 프로덕션에서 크래시를 일으켰습니다.