iOS/문법

Swift 문법과 친해지기 - 패턴

HJ39 2023. 1. 6. 23:22

Swift 패턴에는 크게 두 가지가 존재한다.

  • 어떤 종류의 값과 일치하는 패턴
  • 어떤 종류의 값과 일치하지 않는 패턴

2가지 종류의 패턴들은 또 여러 가지 패턴으로 구분되어 있다.

  • 어떤 종류의 값과 일치하는 패턴
    • 와일드카드 패턴
    • 식별자 패턴
    • 값 바인딩 패턴
    • 튜플 패턴
  • 어떤 종류의 값과 일치하지 않는 패턴
    • 열거형 케이스 패턴
    • 옵셔널 패턴
    • 타입 캐스팅 패턴
    • 표현 패턴

 

 

어떤 종류의 값과 일치하는 패턴

단순 상수, 변수 및 옵셔널 바인딩에서 값을 소멸시키는 데 사용된다.

어노테이션을 지정하여 특정 유형과 일치하도록 제한을 둘 수 있다.

 

와일드카드 패턴

와일드카드 패턴은 모든 값을 일치시키고 무시하며 밑줄(_)로 구성된다.

 

□ 와일드카드 패턴 예시

let hello = ("안녕","hi")

switch hello{
case ("안녕",_):
    print("안녕하세요")
    fallthrough
case (_,"hi"):
    print("Hi")
case (_,_):
    print("안녕, hi")
}

for _ in 1...3{
    print("hi")
}

_를 통해 값을 무시할 수 있다.

 

식별자 패턴

모든 값과 일치하고, 일치된 값을 상수 또는 변수 이름에 매치시킨다.

 

□ 식별자 패턴 예시

let value: Int = 10

우리가 평소에 당연하게 사용했던 변수지만 10이라는 값과 value의 타입이 일치할 때 value는 10이라는 값의 식별자가 된다.

'10은 value라는 상수의 바인딩된다' 라고 한다.

 

값 바인딩 패턴

일치하는 값을 상수 또는 변수 이름에 바인딩 한다.

값 바인딩 패턴은 let으로 시작하지만 변수 이름에 바인딩하는 변수는 var로 시작한다.

 

□ 값 바인딩 패턴 예시

let point = (2,1)

switch point{
case let(x,y):
    print("x= \(x), y=\(y)")
}

튜플로 구성된 요소를 두 개의 요소로 분류하여 식별자 패턴에 바인딩할 수 있다.

 

튜플 패턴

튜플 패턴은 위에 예시들에서 모두 사용하였다.

와일드카드 패턴, 식별자 패턴, 옵셔널 패턴, 다른 튜플 패턴 등에서 사용할 수 있다.

 


어떤 종류의 값과 일치하지 않는 패턴

전체 패턴 매칭에 사용

switch 구문, do-catch, if case, while, guard, for-in 구문으로 구성되어 있다.

 

열거형 케이스 패턴

값을 열거형 타입의 case와 배치시킨다.

 

switch-case , if, while, guard, for-in 구문의 조건에서 볼 수 있다.

 

□ 참고한 블로그 예제

enum MainDish {
    case pasta(taste: String)
    case pizza(dough: String, topping: String)
    case chicken(withSauce: Bool)
    case rice
}

var dishes: [MainDish] = []
var dinner: MainDish = .pasta(taste: "까르보나라")
dishes.append(dinner) //까르보나라

if case .pasta(let taste) = dinner {
    print("\(taste) 파스타") //까르보나라 파스타
}

dinner = .pizza(dough: "치즈크러스트", topping: "쉬림프")
dishes.append(dinner)

func whatIsThis(dish: MainDish) {
    guard case .pizza(let dough, let topping) = dinner else {
        print("이것은 피자가 아닙니다")
        return
    }
    print("\(dough) \(topping) 피자")
}

whatIsThis(dish: dinner) //치즈크러스트 쉬림프 피자

위 예제와 같이 열거형을 여러 가지 패턴들에 적용하여 사용할 수 있다.

 

옵셔널 패턴

옵셔널 패턴은 식별자와 그 뒤에 ? 로 구성되어 있다.

 

for-in 구문을 사용하여 배열 옵셔널 값을 제외하고 출력시킬 수 있다.

let arr : [Int?] = [nil,1,2,nil,3,nil,4]

for case let num? in arr{
    print("\(num)")
}

for-in 구문에 case let을 적용하여 사용한 예제이다.

 

타입 캐스팅 패턴

is 패턴은 switch-case 구문에서만 사용가능하다.

as 패턴은 다른 패턴 as 패턴 이름으로 사용가능하다.

 

표현 패턴

패턴들 중 가장 최고의 패턴 매칭이 가능한 패턴이라고 한다.

~=는 switch-case문 안에서 사용된다.

 

swift에서 표준 라이브러리의 패턴연산자 중 ~=연산자로 간단하게 비교 연산을 할 수 있다.

let val = 10

if val>=0 || val<=10{
    print("val is in range")
}

if 0...10 ~= val{
    print("val is in range")
}

 if문을 사용할 때 조건 식을 적어야 하지만 ~=을 사용하고 간단하게 작성이 가능하다.

 

~=연산자는 오버로딩도 가능하다.

이 기능을 보고 소름 돋았다...

 

□ 예시

let point = (1, 2) //Int 값이 있는 튜플

func ~= (pattern: String, value: Int) -> Bool {
    return pattern == "\(value)"
}

switch point {
case ("0", "0"):
    print("(0, 0)은 원점입니다.")
default:
    print("점은 (\(point.0), \(point.1)) 입니다.")
}
// Prints "점은 (1, 2) 입니다."

point라는 튜플을 switch-case문으로 검사할 때 case문 안에 String타입으로 되어 있다. 하지만 튜플은 (Int, Int) 타입으로 되어 있다.

Int타입과 String타입은 비교가 되지 않지만 위 함수에서 ~=를 오버로딩하여 가능하게 되었다.

 

swift언어를 계속 공부할수록 새로운 내용이 계속 나온다..

 

 

 

# 참고한 사이트

  1. https://seons-dev.tistory.com/entry/Swift-%EA%B3%A0%EA%B8%89-%EB%AC%B8%EB%B2%95-%ED%8C%A8%ED%84%B4-Patterns