BOID

[swift] 스위프트에서 사용하는 패턴(열거형 케이스 패턴, 옵셔널 패턴, 타입 캐스팅 패턴) - HoonIOS 본문

swift 시작기

[swift] 스위프트에서 사용하는 패턴(열거형 케이스 패턴, 옵셔널 패턴, 타입 캐스팅 패턴) - HoonIOS

HoonIOS 2021. 3. 26. 16:43

안녕하세요 HoonIOS입니다. :)

저번 포스팅에는 값을 해체(추출)하거나 무시하는 패턴의 종류에 대해 알아봤는데요, 이번 포스팅에는 패턴 매칭을 위한 패턴의 종류에 대해 알아보겠습니다.

 

표현 패턴은 내용이 길이서 다음 포스팅 때 따로 표현 패턴만 포스팅할게요 ㅎㅎ

  • 패턴 매칭을 위한 패턴 종류
    - 열거형 케이스 패턴, 옵셔널 패턴, 표현 패턴, 타입캐스팅 패턴

 

열거형 케이스 패턴이란?

- 열거형 타입은 case 조건과 매치시킵니다.

- 이 패턴은 switch 구문의 case레이블과 if,while, guard, for-in 구문의 case조건에서 볼 수 있습니다.

- 연관값이 있는 열거형 케이스와 매치하려고 한다면 열거형 케이스 패턴에는 반드시 튜플 패턴이 함께 해야 합니다.

  • 연관 값은 각 하나의 타입에 대해 인스턴스마다 다른 값을 가지게 할 때 사용한다.

- 열거형 케이스 패턴 예제를 살펴보겠습니다.

let someValue: Int = 20

if case 0...100 = someValue {
	print("0 <= \(someValue) <= 100") // 0 <= 20 <= 100
}

let anotherValue: String = "ABC"

if case "ABC" = anotherValue {
	print(anotherValue) // ABC
}

- if문을 이용해 if 뒤에 case를 붙여 해당 케이스가 맞으면 블록 안에 코드를 실행하는 열거형 케이스입니다.

 

- enum 열거형을 통한 예제를 한번 살펴보겠습니다.

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) //크림파스타 dinner변수 배열에 추가

if case .pasta(let taste) = dinner {
	print("\(taste) 파스타")
}

dinner = .pizza(dougj: "치즈크러스트", topping: "불고기")
dishes.append(dinner) //치즈크러스 불고기피자 dinner 변수 배열에 추가

func whatIsThis(dish: MainDish) {
	guard case .pizza(let dough, let topping) = dinner else {
    	print("어? 피자가 아닌데?")
        return
    }
    print("\(dough) \(topping) 피자")
}

whatIsThis(dish: dinner)

dinner = .chicken(withSauce: true)
dishes.append(dinner) //양념 치키 변수 배열에 추가

while case .chicken(let sauced) = dinner {
	print("\(sauced ? "양념" : "후라이드") 통닭")
    break
}

dinner = .rice
dishes.apped(dinner) //쌀 열거형이 포함된 dinner변수 추가

for dish in dishes { //dishes 안에 넣은 값들 for문으로 switch로 변수 값 출력
	switch dish {
    case let .pasta(taste):
    	print(taste)
    case let .pizza(dough, topping):
    	print(dough, topping)
    case let .chicken(withSauce):
    	print("\(withSauce ? "양념" : "후라이드)")
    case .rice:
    	print("그냥 쌀")
    }
}
/* 출력값
크림
치즈클러스트 불고기
양념
그냥 쌀
*/

- 예제 문을 보면은 case 열거형 변수명(let 변수명)을 통해 값을 넣어 출력하는 것을 볼 수 있습니다.

 

옵셔널 패턴

- 옵셔널 또는 암시적 추출 옵셔널 열거형에 감싸져 있는 값을 매치실 때 사용합니다.

- 옵셔널 패턴은 식별자 패턴 뒤에 물음표를 넣어 표기하여 열거형 케이스 패턴과 동일 위치에 자리합니다.

- 이 옵셔널 패턴이 유연하게 사용하는 곳은 옵셔널 값을 저장하는 배열의 for-in구문을 통한 순환에서 nil이 아닌 값을 찾는데도 유용하게 사용한다.

 

- 다음은 예시를 통해 한번 알아보겠습니다.

var optionalValue: Int? = 100

if case .some(let value) = optionalValue { //.some은 옵셔널 값을 보면 switch 는 .some
	print(value)
}

if case let value? = optionalValue { //옵셔널 바인딩
	print(value)
}

func isItHasValue(_ optionalValue: Int?) {
	guard case .some(let value) = optionalValue else {
    	print("nil")
        return
    }
    print(value)
}

isItHasValue(optionalValue)

while case .some(let value) = optionalValue {
	print(value)
    optionalValue = nil //만약 nil로 바꾸지 않으면 무한루프를 돌기 때문에
}

print(optionalValue)

let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]

for case let numbers? in arrayOfOptionalInts { // numbers? 에 ?옵셔널이 붙지 않으면 바인딩도 안되고 nil값도 그대로 출력된다.
	print("real Number: \(numbers)")
}

-  위 예시를 보면 있는. some은 옵셔널 enum 타입으로. some ,. nome 케이스가 존재합니다 만약 값이 있으면 some의 값을 타고 옵셔널로 쌓여있던 wrapped가 나오게 됩니다.

타입 캐스팅 패턴

- 타입 캐스팅 패턴에는 is패턴과 as패턴이 있습니다.

- is패턴은 switch의 case 레이블에서만 사용할 수 있고 is (TYPE_NAME)과 같이 쓸 수 있습니다.

- as패턴은 SomePattern as (TYPE_NAME)과 같이 쓸수 있습니다.

- is와 as는 타입 캐스팅 문법과 같이 타입이 is우측에 쓰인 타입 또는 그 타입의 자식 클래스이면 값과 매칭을 시킵니다.

- as 패턴은 프로그램 실행 중에 값의 타입이 as 우측에 쓰인 타입 또는 그 타입의 자식 클래스 타입의 값과 매칭 시키고 만약 매칭이 된다면 원하는 타입으로 캐스팅이 됩니다.

 

let someValue: Int = 100

switch someValue {
case is String:
	print("이것은 문자열")
    //타입 확인과 동시에 캐스팅까지 완료되어 value에 저장
    //값 바인딩 패턴과 결합된 모습
case let value as Int:
	print(value + 1)
default:
	print("Int String 둘다 아님요")

- switch를 통해 그 타입이 Int인지 String인지 case별로 나뉜 다음에 해당하는 case를 실행한다.

 

지금까지 패턴 매칭을 위한 패턴 종류에서 표현 패턴에 뺀 나머지에 대해 알아봤는데요, 표현 패턴은 너무 많아서 다음 포스팅에 올리려고요 ㅠㅠㅠ 

어려울 수 있지만 어려울수록 자주 반복해서 봐야 될 거 같습니다 :)

반응형
Comments