iOS/Swift

흐름 제어 (switch 구문)

밤새는 탐험가89 2024. 1. 11. 12:08

 

위프트에서 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을 통해 이런 문제를 방지하고자 함 ★

'iOS > 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