아요 개발 일기

[Swift] 조건문 - Switch case 본문

Swift/Grammar

[Swift] 조건문 - Switch case

소진이 2023. 1. 29. 15:06

1. Switch case 구문

Switch 구문은 앞에서 다룬 if 와 guard 처럼 분기문의 일종이지만, 처리 방식은 앞에서와 다릅니다.

switch 구문은 입력받은 값을 조건식 여부가 아니라 패턴으로 비교하고 그 결과를 바탕으로 실행 블록을 결정하는 조건문입니다.

 

Switch 구문 형태

switch [비교 대상] {
	case [비교 패턴1] :
    	[비교 패턴1이 일치했을 때 실행할 구문]
    case [비교 패턴2], [비교 패턴3] :
    	[비교 패턴2 또는 3이 일치했을 때 실행할 구문]
    default:
    	[어느 비교 패턴과도 일치하지 않았을 때 실행할 구문]
 }

 

Switch문 문법

 

  • 각 상태는 키워드 case를 통해 나타낼 수 있습니다.
  • case 상태 끝에 콜론 ':'을 붙여 패턴을 종료합니다.
  • 하나의 case문이 종료되면 switch 문이 종료됩니다.
  • switch문은 모든 경우를 커버하기 위해서 마지막에 default 키워드를 사용해야합니다.

 

C나 자바 등 많은 언어에도 switch 구문이 있고 문법 역시 유사하지만, 실행 방식에서는 결정적인 차이점이 존재합니다.

무엇일까요?

 

  • C나 자바일 경우

       비교 패턴이 일치할 경우 우선 실행 구문을 처리한 다음, 나머지 case에 대한 비교를 계속 진행합니다.

       추가로 일치하는 패턴이 있다면 이를 모두 실행하고, 마지막 case를 비교한 후에야 분기문을 종료합니다.

 

  • 스위프트일 경우

      일치하는 비교 패턴이 있을 경우 해당 블록의 실행 코드를 처리하고, 더이상의 비교 없이 전체 분기문을 종료합니다.

      즉, 맨 처음 일치하는 case 구문 하나만 실행하죠. (그래서 break 구문을 스위프트에서 생략할 수 있음)

 

이해가 어렵다면 아래의 예시 코드를 볼까요?

let val = 2

switch val {
	case 1 : 
    	print("일치한 값은 1입니다.")
    case 2 :
    	print("일치한 값은 2입니다.")
    case 3 :
    	print("일치한 값 2가 더 있습니다.")
   	default : 
    	print("어느 패턴과도 일치하지 않았습니다")
}

-------------------------------------------------------------------------

swift 실행 결과

일치한 값은 2입니다.

-------------------------------------------------------------------------

c와 자바에서의 실행 결과

일치한 값은 2입니다.
일치한 값 2가 더 있습니다.
어느 패턴과도 일치하지 않았습니다.

1-2. switch 구문에서의 Fall Through

switch 구문에는 패턴이 일치하는 case 블록을 실행하는 대신, 그 다음 case 블록으로 실행 흐름을 전달하는 문법을 말합니다.

 

  • 스위프트 : 명시적 Fall through

스위프트 

let sampleChar : Character = "a"

switch sampleChar {
	case "a" :
    	fallthrough
    case "A" :
    	print("글자는 A 입니다.")
    default :
    	print("일치하는 글자가 없습니다.")
}

-------------------------------------------------------------------------

실행 결과

글자는 A 입니다.

 

예제 코드를 살펴보면 case"a" 안에 fallthrough가 명시되어있습니다.

스위프트에서는 암시적인 Fall through를 지원하지 않으며, case 실행 블록이 비어있어서도 안됩니다.

 

Q.Fall through는 항상 다음 case문에만 걸리는 건가요? 아니면 일치하는 case문에 걸리나요?

A: Fall through는 무조건 다음 case문에 걸려서 종료됩니다.

 


1-3. switch 구문의 특성

 

1. 반드시 default 구문을 추가하여야 합니다. 

 

스위프트에서 switch 구문에 사용된 비교 대상은 반드시 하나의 비교 패턴과 일치해야 합니다. 이에 따라 모든 case 구문에서 일치된 패턴을 찾지 못했을 경우에 대비하여 switch 구문에는 반드시 default구문을 추가해야하며, 만약 default를 생략하면 완전하지 않은 구문으로 간주하여 오류가 발생합니다. (단, default 구문을 대신하여 모든 패턴을 매칭시킬 수 있는 구문이 존재하는 경우에 한하여 default 구문 생략 가능)

 

2. case 비교 패턴을 작성할 때, 하나의 case 키워드 다음에 하나 이상의 비교 패턴을 연이어 작성할 수 있습니다.

 

두 가지 이상의 패턴에 대해 같은 구문을 실행해야 한다면, 하나의 case 키워드로 비교 패턴을 묶어 표현하면 됩니다.

이는 키 입력의 낭비를 줄이고 코드를 줄이고 코드를 보다 간결하게 만드는게에 효과적입니다.

 

var value = 3

switch value {
	case 0,1 :
    	print("0 또는 1입니다.")
    case 2,3 :
    	print("2 또는 3입니다.")
    default :
    	print("default 입니다.")
}

-------------------------------------------------------------------------

실행 결과

2 또는 3입니다.

 

3. switch 구문에서 튜플 내부의 아이템이 비교 대상과 부분적으로 일치할 경우, 스위프트는 case 구문의 비교 패턴 전체가 일치하는 것으로 간주합니다.

 

이때, 일치하지 않는 나머지 부분을 상수나 변수화하여 사용할 수 있습니다. 

잘 이해가지 않는 다면 아래 예제를 같이 봅시다.

var value = (2,3)

switch value {
	case let (x,3) : 
    	print("튜플의 두 번째 값이 3일 때 첫 번째 값은 \(x)입니다.")
    case let (3,y) :
    	print("튜플의 첫 번때 값이 3일 때 두 번때 값은 \(y)입니다.")
    case let (x,y) :
    	print("튜플의 값은 각각 \(x)\(y)입니다.")
}

-------------------------------------------------------------------------

실행 결과

튜플의 두 번째 값이 3일 때 첫 번째 값은 2입니다.

 

위 예제에서 비교대상 (2,3)과 부분적으로 일치하는 case 문을 실행하는 것을 볼 수 있습니다.

위 예제들 뿐만 아니라 switch 문을 다양하게 응용하여 사용할 수 있는데요. 더 많은 예제도 살펴 볼까요?


1-4. 예제

 

(1) IntervalMatching 

 

interval Matching이란 범위 연산자를 활용하여 단순히 값을 매칭하는 것뿐만이 아니라 다양한 패턴을 이용하여 매칭하는 것을 말합니다. 

 

 -> 글이 작성된 시간(초)을 범위에 따라 그룹지어 표현해주는 예시

var passtime = 1957

switch passtime {
	case 0..<60 :
    	print("방금 작성된 글입니다.")
    case 60..<3600 :
    	print("조금 전 작성된 글입니다.")
    case 3600..<86400 :
    	print("얼마 전 작성된 글입니다.")
    default :
    	print("예전에 작성된 글입니다.")
}

---------------------------------------------------------------------

실행 결과

조금 전 작성된 글입니다.

 

 

Q. 튜플(tuple)이 뭐야?

: 집단 자료형으로서, 괄호로 묶인 이형 집단 데이터 입니다.

자세한 설명은 집단 자료형 링크로 들어가면 알 수 있습니다.

 

 

(2) 튜플 매칭

 

-> 튜플 형식의 테이터 비교하는 예시

var value = (2,3)

switch value {
	case (0..<2,3) :
    	print("범위 A에 포함되어있습니다.")
    case (2..<5, 0..<3) :
    	print("범위 B에 포함되어있습니다.")
    case (2..<5, 3..<5) :
    	print("범위 C에 포함되어있습니다.")
    default:
    	print("범위 D에 포함되어있습니다.")
}       

-------------------------------------------------------------------------

실행 결과

범위 C에 포함되어있습니다.

 

(3) 값 바인딩

 

- > 좌표를 이용한 바인딩 예시

var value = (-1,0)

  switch value {
    case (0, 0):
        print("\(value)는 원점 입니다.")
    case (let x, 0):
        print("좌표는 \(x),0 입니다.")
    case (0, let y):
        print("좌표는 0,\(y) 입니다.")
    case (-2...2, -2...2):
        print("\(value) 값은 해당 범위 안에 있습니다.")
    default:
        print("\(value) 값은 해당 범위 밖에 있습니다.")
    }
}

-------------------------------------------------------------------------

실행 결과

좌표는 -1,0입니다.

 

 

(4) where 문

 

이 예제는 튜플 값을 변수에 담고 조건 검사까지 한 경우입니다.

 

-> 좌표축의 값을 받아 문장으로 표현해주는 예시

var point = (3,-3)

switch point {
    case let (_,y) where -3 == y :
        print("\(y)은 -3==y 선 상에 있습니다.")
    case let (x,y) where x == y :
        print("\(x)과 \(y)은 x==y 선 상에 있습니다.")
    case let (x,y) where x == -y :
        print("\(x)과 \(y)은 x==-y 선 상에 있습니다.")
    case let (x,y) :
        print("\(x)과 \(y)은 일반 좌표상에 있습니다.")
}

---------------------------------------------------------------------------

실행 결과

3은 -3==y 선 상에 있습니다.

 

 

(5) Enum 응용

 

enum Barcode {

    case upc(Int, Int, Int, Int)

    case qrCode(String)

}



var product = Barcode.upc(8, 85909, 51226, 3)

product = .qrCode("ABCDEFG")



switch product {

case .upc(let numberSystem, let manufacturer, let product, let check):

    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")

case .qrCode(let productCode):

    print("QR code: \(productCode).")

}

 

 

'Swift > Grammar' 카테고리의 다른 글

[Swift] Guard문  (0) 2023.01.29
[Swift] Enum - 열거형  (0) 2023.01.29
[Swift] Struct - 구조체  (0) 2023.01.27
[Swift] Class - 클래스  (0) 2023.01.27
[Swift] 고차 함수  (0) 2023.01.27