김경록의 앱 개발 여정

[Swift] Swift의 패턴 매칭(Pattern Matching) 기능을 효과적으로 사용하는 방법은 무엇인가요? 본문

TIL

[Swift] Swift의 패턴 매칭(Pattern Matching) 기능을 효과적으로 사용하는 방법은 무엇인가요?

Kim Roks 2025. 1. 9. 18:46

개념 정리

패턴

  • 단독 또는 복합 값의 구조를 나타내는 것

패턴 매칭

  • 데이터를 검색할 때 특정 패턴이 출현하는지, 또한 어디에 출현 하는지 등을 특정하는 방법의 일종(in CS)
  • 코드 내에서 특정 패턴과 값을 비교하고 일치 여부를 확인 하는 방법

→ ~~한 것을 표현하고 싶다면 ~~한 패턴을 통해 표현 가능

 

swift의 패턴은 크게 두 종류로 나뉘는데

  1. 값을 해체(추출) 하거나 무시하는 패턴
    1. 와일드 카드 패턴
    2. 식별자 패턴
    3. 값 바인딩 패턴
    4. 튜플 패턴
  2. 패턴 매치을 위한 패턴
    1. 열거형 케이스 패턴
    2. 옵셔널 패턴
    3. 표현 패턴
    4. 타입 캐스팅 패턴

와일드 카드 패턴

let someValue = 10

switch someValue {
case 0:
    print("Value is zero")
case _:
    print("Value is something else")
}
  • 와일드 카드 패턴은 어떤 값과도 일치하지만 그 값을 무시합니다
  • 이 자리에 올 것이 무엇이든간에 상관하지 마라. 라는 뜻

식별자 패턴(identifier Pattern)

var SomeValue: Int = 28
  • 변수 또는 상수의 이름에 알맞는 값을 어떤 값과 매치시키는 패턴
  • 이런 이름이 있었구나 싶음..

값 바인딩 패턴

let anotherPoint = (3, 2)

switch anotherPoint {
case (let x, 0):
    print("The point is on the x-axis with an x value of \(x)")
case (0, let y):
    print("The point is on the y-axis with a y value of \(y)")
case let (x, y):
    print("The point is at (\(x), \(y))")
}
  • 보통 Switch 문에서 자주 활용됨
  • 변수 또는 상수의 이름에 매치된 값을 바인딩 하는 것.

튜플 패턴

let (x,y): (Int, Int) = (1, 2)
  • 소괄호 내에 쉼표로 분리하는 리스트
  • 알고리즘 풀이하면서 readLine 분리할 때 유용한 그것

열거형 케이스 패턴

enum Direction {
    case north, south, east, west
}

let value = Direction.south

switch heading {
case .north:
    print("north")
case .south:
    print("south")
case .east:
    print("east")
case .west:
    print("west")
}

// South 출력
  • 값을 열거형 타입의 case와 매치시킵니다.
  • 연관값이 있는 enum과 매치 하려고 한다면 enum에는 반드시 튜플 패턴이 함께 해야함

옵셔널 패턴

let someValue: Int? = 10

switch someValue {
case .some(let x):
    print("Value is \(x)")
case .none:
    print("Value is nil")
}
  • 옵셔널 열거형에 감싸져 있는 값을 매치시킬 떄 사용
  • 이 때, .some 에서 선언된 x는 옵셔널 타입이 아님
  • 옵셔널 값을 저장하는 배열을 순환하는 for문에서 nil이 아닌 값을 찾는데도 유용함

타입 캐스팅 패턴

let someValue: Any = 10

switch someValue {
case is String:
    print("Value is a string")
case is Int:
    print("Value is an integer")
default:
    print("Unknown type")
}

//Value is an integer 출력
  • 타입캐스팅을 하거나 타입을 매치 시킬때 사용
  • is, as 가 있음
  • as는 원래 많이 보시던 그것 맞음
  • is 는 switch 에서만 사용 가능
  • is 사용시엔 타입을 확인은 하지만 캐스팅 된 값은 사용할 수는 없다.

표현 패턴

let someValue = 42

switch someValue {
case 0:
    print("Value is zero")
case 1...10:
    print("Value is between 1 and 10")
case 42:
    print("Value is the answer to life, the universe, and everything")
default:
    print("Value is something else")
}
  • switch 구문 내 case 레이블에서만 사용 가능.
  • 기본적으로 switch 구문 내부적으로 ~= 연산자를 사용하여 각 someValue가 case와 일치하는 지 일치하는 방식
  • ~= 연산자를 오버로드 하여 커스텀 패턴을 구현하는 방법도 있지만 이 포스팅에선 제외

이제 본 목적이었던 면접 질문으로 되돌아 가보면,

Swift의 패턴 매칭(Pattern Matching) 기능을 효과적으로 사용하는 방법은 무엇인가요?

  • switch문을 사용하여 모든 가능한 케이스를 명확히 처리할 수 있습니다.

switch 문과 패턴 매칭을 사용할 때의 모범 사례는 무엇인가요?

  • 패턴 매칭을 사용하면 코드의 가독성을 높이고 복잡한 조건을 간결하게 표현 할 수 있습니다.
    이의 모범 사례를 네트워크 처리 상황에서의 Result타입을 예시로 설명 드리겠습니다.
  • Result 타입은 네트워크 요청의 성공과 실패 두가지 결과를 가집니다.
    Switch 문과 패턴 매칭을 사용하여 각 결과에 대한 처리를 명확히 할 수 있다는 장점이 있습니다.
  • 또한 실패시에, 명확한 에러 처리 분기를 나눈다면 패턴 매칭의 장점을 더욱 잘 활용 할 수 있을거라 생각합니다.

패턴 매칭을 사용하여 복잡한 데이터 구조를 처리하는 예시는 무엇인가요?

  • 복잡한 구조의 Json 데이터를 파싱하는 경우를 예시로 들 수 있을 것 같습니다.
  • 예시로 나이 정보가 포함된 고객 관리용 Json을 처리한다고 했을때, switch 문과 where절을 통한 패턴 매칭을 통해 일정 나이 이상의 고객을 추려내는 식의 간결한 처리가 가능할 것이라 생각합니다.

 

참조: https://github.com/JeaSungLEE/iOSInterviewquestions/blob/master/oldREADME.md