본문 바로가기
Swift

흐름 제어 (switch 구문)

by 밤새는 탐험가89 2024. 1. 11.
728x90
SMALL

 

위프트에서 switch 구문은 다음과 같은 특징이 있음

1. 소괄호 () 생략 가능

2. break 키워드는 선택 사항

(case 의 비교값을 비교하여 참이면 내부 코드 실행후 switch 구문 탈출)

3. switch 구문의 조건에는 다양한 타입의 값 입력 가능 

4. 비교될 값이 명확한 경우 (열거형 값 등)가 아니라면? default 를 반드시 작성

 

 

 

switch 구문 기본 구현

let checkNumber: Int = 1000

switch checkNumber {
    case 0 :
    print("checkNumber의 값은 0입니다.")
    case 1...100:
    print("checkNumber의 값은 1부터 10 사이에 있습니다.")
    case 101...1000:
    print("checkNumber의 값은 101부터 1000 사이에 있습니다.")
    fallthrough
    default:
    print("checkNumber의 값은 \(checkNumber)")
}

// checkNumber의 값은 101부터 1000 사이에 있습니다.
// checkNumber의 값은 1000

 

위의 결과에서 case: 100...1000 비교값이 참이므로 

결과를 출력하고 switch 구문을 탈출해야 하지만 

"fallthrough" 라는 키워드 때문에 다음 비교 구문으로 넘어감

 

switch 구문에서는 정수타입의 값 뿐아니라 부동소수, 문자열 등 비교 가능 

 

case 내부에는 비교 값이 참일경우 실행할 코드가 반드시 있어야 함 

(없다면 오류 발생)

만약에 실행할 코드가 없다면?

"fallthrough"를 통해 넘어가기 가능 

 

 

 

fallthrough의 사용

switch checkNumber {
    case 0 :
    print("checkNumber의 값은 0입니다.")
    case 1...100:
    // case의 비교가 참일 경우 실행할 내부 코드가 없는 경우 
    // 오류 발생함 
    // fallthrough 키워드를 통해 오류 해결 
    case 101...1000:
    print("checkNumber의 값은 101부터 1000 사이에 있습니다.")

 

 

 

 

와일드 카드 식별자를 사용한 튜플 switch case 구성

typealias FruitPrice = (name: String, price: Double)

let redFruit: FruitPrice = ("Apple", 3000.15)

switch redFruit {
    case ("Apple", _ ):
    print("오우 과일 이름만 맞추셨어요")
    fallthrough
    case (_, 3000.00...3050.00) :
    print("가격만 맞추셨어요")
    fallthrough
    case("Apple", 3000.00...3050.00):
    print("정확히 맞추셨어요")
    default:
    print("뭘까요?")
}

// 오우 과일 이름만 맞추셨어요
// 가격만 맞추셨어
// 정확히 맞추셨어요

 

 

와일드 카드 식별자를 사용할 경우 무시된 값을 직접 가져와야 하지만

let을 붙인 바인딩을 통해 지정된 조건 값을 제외한

다른 값은 실행문 안으로 가져올 수 있음

 

 

 

값 바인딩을 사용한 튜플 switch case 구성

typealias FruitPrice = (name: String, price: Double)

let redFruit: FruitPrice = ("Apple", 3000.15)

switch redFruit {
    case ("Apple", let price ):
    print("오우 과일 이름만 맞추셨어요 가격은 \(price)이에요")
    
    case (let name, 3000.00...3050.00) :
    print("가격만 맞추셨어요. 이름은 \(name)이에요")
    
    case("Apple", 3000.00...3050.00):
    print("정확히 맞추셨어요")
    
    default:
    print("뭘까요?")
}

// 오우 과일 이름만 맞추셨어요 가격은 3000.15 이에요

 

★ 이때, fallthrough 키워드 사용 안됨

 

 

 

열거형을 입력 값으로 받는 switch 구문

enum Fruit {
    case apple
    case mango
    case melon
}

let likeFruit: Fruit = .apple

switch likeFruit {
    case .apple:
    print("\(Fruit.apple)을 제일 좋아합니다.")
    case .mango:
    print("\(Fruit.mango)을 제일 좋아합니다.")
    case .melon:
    print("\(Fruit.melon)을 제일 좋아합니다.")
}

// apple을 제일 좋아합니다.

 

 

만약에 열거형에 case를 추가할 경우

switch 구문에서는 어떻게 대응해야 할까?

 

이 경우에는 @unknown 키워드를 통해 대응

 

차후에 Fruit 열거형에 추가한 case를 처리하지 않으면 경고를 내어줄 unknown 속성

enum Fruit {
    case apple
    case mango
    case melon
    case kiwi
}

let likeFruit: Fruit = .apple

switch likeFruit {
    case .apple:
    print("\(Fruit.apple)을 제일 좋아합니다.")
    case .mango:
    print("\(Fruit.mango)을 제일 좋아합니다.")
    case .melon:
    print("\(Fruit.melon)을 제일 좋아합니다.")
    
    @unknown case _:             // switch must be exhaustive
    print("어떤 과일이죠?")  
}

// apple을 제일 좋아합니다.

 

 

Fruit 열거형을 생성한 뒤 차후에 추가할 case에 대응하기 위해 

switch 구문 마지막에 @unknown case _:를 작성

(@unknown 은 case _ 또는 default: 앞에서만 사용)

 

나중에 Fruit 열거형에 case kiwi를 추가했다는 가정하에 

switch 구문을 실행하면 @unknown case _: 에서 오류 (switch must be exhaustive) 발생

 

이 때 case 비교 구문에 맞는 결과는 실행된다. 

 

@unknown의 속성을 부여한 case는 항상 switch 구문 마지막에 작성

 

★ @unknown은 사용하지 않고, default: 또는 case _ :로도 컴파일 오류 빼곤 

문법적으로는 오류가 없지만, 논리적 오류가 발생할 여지가 있기 때문에 

@unknown을 통해 이런 문제를 방지하고자 함 ★

728x90
LIST

'Swift' 카테고리의 다른 글

함수 1편 (함수 정의 및 호출)  (0) 2024.01.14
흐름 제어 (반복문)  (0) 2024.01.12
흐름 제어 (if 구문)  (0) 2024.01.10
연산자  (1) 2024.01.09
데이터 타입 고급 4편 (열거형 2탄)  (1) 2024.01.08