맨위로가기

Switch 문

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

Switch 문은 프로그래밍 언어에서 제어 흐름을 변경하는 데 사용되는 구문으로, 제어식의 값에 따라 여러 코드 블록 중 하나를 선택하여 실행한다. 1952년 스티븐 클리니가 CASE 함수를 증명하면서 개념이 시작되었으며, 대부분의 언어에서 `switch`, `case`, `default` 등의 키워드를 사용한다. C 계열 언어는 폴스루(fallthrough)를 허용하지만, C#은 이를 금지하며, 파스칼, PL/I, 포트란, BASIC 등의 언어는 폴스루를 허용하지 않는다. 컴파일러는 switch 문을 분기표 또는 이진 검색으로 최적화하며, if-else 문보다 디버깅이 쉽고, 가독성이 높으며, 고정된 깊이를 가지는 장점이 있다. C/C++, C#, Java, JavaScript, PHP, Python, Ruby, Go, BASIC 등 다양한 언어에서 switch 문을 지원하며, 언어별로 구문과 기능에 차이가 있다. Switch 문은 if-else 문, 룩업 테이블, 제어 테이블, 패턴 매칭 등으로 대체될 수 있다.

더 읽어볼만한 페이지

  • 조건문 - 패턴 매칭
    패턴 매칭은 데이터 구조나 문자열에서 특정 패턴을 찾아 식별하는 기법으로, 다양한 프로그래밍 언어와 시스템에서 사용되며 데이터 필터링, 추출 및 선언적 프로그래밍에 중요한 역할을 수행한다.
  • 조건문 - 분기 테이블
    분기 테이블은 프로그램 실행 흐름을 제어하는 자료 구조로, 조건에 따라 여러 코드 블록 중 하나를 선택적으로 실행하여 복잡한 조건문을 간소화하고 코드의 가독성과 유지보수성을 높이며, 인터프리터, 컴파일러, 가상 머신 등에서 명령어 디스패치 메커니즘으로 활용된다.
  • 프로그래밍 구성체 - 형 변환
    형 변환은 프로그래밍에서 변수의 데이터 타입을 변경하는 것으로, 암시적 형 변환과 명시적 형 변환으로 나뉘며, 객체 지향 프로그래밍에서는 업캐스팅과 다운캐스팅이 발생하고, 각 언어는 고유한 규칙과 방법을 제공하며 잘못된 형 변환은 오류를 유발할 수 있다.
  • 프로그래밍 구성체 - 연산자 오버로딩
    연산자 오버로딩은 프로그래밍 언어에서 기존 연산자를 사용자 정의 자료형에 대해 재정의하여 내장 자료형처럼 다루도록 하는 기능으로, 코드 가독성과 표현력을 높이지만 남용 시 코드 의미를 모호하게 만들 수 있다.
Switch 문
스위치 문
종류제어 흐름 문
설계 패러다임구조적 프로그래밍
언어 지원
지원 언어C
C++
C#
Java
JavaScript
PHP
Swift
Visual Basic
Rust
Go
Scala
Python (match 문, 3.10 버전부터)
Delphi
Pascal
Ada
Perl
Haskell
SQL
Shell script
대체재
대체재if-then-else 문

2. 역사

스티븐 클리니는 1952년 저서 ''수리철학 입문''에서 CASE 함수(IF-THEN-ELSE 함수의 가장 단순한 형태)가 원시 재귀 함수임을 증명했다.[3]

IF-THEN-ELSE는 매카시 형식의 기초이며, 원시 재귀와 뮤 연산자를 대체한다.

최초의 포트란 컴파일러는 다중 분기를 위해 계산된 GOTO 문을 지원했다. 초기 ALGOL 컴파일러는 "설계 표현식" 목록을 포함하는 SWITCH 데이터 유형을 지원했다. BCPL, ALGOL-W, ALGOL-68과 같은 언어는 현대 언어에서도 살아남은 다중 분기 구조를 도입했다.

3. 구문 및 의미

대부분의 프로그래밍 언어에서 switch 문은 `switch`, `case`, `default`와 같은 키워드를 사용하여 작성된다. 제어식의 값에 따라 해당하는 `case` 절이 실행되며, 다른 케이스와 일치하지 않을 때 실행되는 선택적 기본 케이스(`default`, `otherwise`, `else` 키워드로 지정)도 허용된다.

의미론적으로 스위치 문에는 두 가지 주요 형태가 있다.


  • 구조적 스위치: 파스칼과 같이 정확히 하나의 분기만 실행되고, 각 케이스가 별개의 배타적 블록으로 취급된다.
  • 비구조적 스위치: C와 같이 각 케이스가 단일 블록 내의 레이블로 취급되고 스위치가 일반화된 goto로 작동한다.


파스칼 계열(Object Pascal, Modula, Oberon, Ada 등), PL/I, 파스칼의 영향을 받은 포트란과 BASIC 방언의 현대적 형태, 대부분의 함수형 언어 등에서는 일치하는 블록만 실행하고, switch 문의 끝에서 실행이 계속된다.

C 언어에서 파생된 언어는 제어가 일치하는 케이스로 이동한 다음 소스 텍스트의 '다음' 케이스와 관련된 문으로 실행이 계속되는 폴스루 기능을 특징으로 한다.

폴스루에 관한 내용은 === 폴스루 (Fallthrough) === 하위 섹션을 참조하라.

C#의 switch문은 다음과 같은 특징을 가진다.

  • case 레이블이 문에 속하는 것으로 취급되지만, 하나의 문에 여러 개의 case 레이블을 붙일 수 있다.
  • C 언어와 같은 폴스루는 금지되어 있다.
  • C나 C++에서는 switch 문의 제어식에 정수형 식, case 레이블에는 정수 상수식만 사용할 수 있지만, C#에서는 문자열형 및 문자열 리터럴도 사용할 수 있다.


구조적 프로그래밍된 BASIC에서는 Select Case 문이 존재하며, 각 Case는 레이블이 아니고 Select 문은 폴스루가 아니다.

3. 1. 폴스루 (Fallthrough)

C, C++, Java, 자바스크립트와 같은 프로그래밍 언어에서는 `break` 문을 생략하여 의도적으로 폴스루를 사용할 수 있다. 그러나 이는 버그의 원인이 될 수 있어 주의해야 한다.[4] 이러한 이유로 린트 도구는 의도적인 폴스루임을 명시하기 위해 `/* FALLTHROUGH */`와 같은 주석을 사용하도록 권장한다.

C#은 폴스루를 허용하지 않지만, `goto case`를 통해 유사한 동작을 구현할 수 있다.

Go는 `fallthrough` 문을 사용하여 명시적으로 폴스루를 허용하며, Perl은 `continue` 키워드를 사용하여 선택적으로 폴스루를 허용한다. Bash는 `;;`로 종료될 때 기본적으로 폴스루하지 않지만, `;&` 또는 `;;&`를 사용하여 폴스루를 허용한다.[5]

4. 컴파일 및 최적화

최적화 컴파일러(컴파일러 최적화)인 GCC 또는 Clang과 같은 컴파일러는 switch 문을 분기표 또는 case 값에 대한 이진 검색으로 컴파일할 수 있다.[6] 분기표를 사용하면 switch 문에서 비교 목록을 거치지 않고도 적은 수의 상수 명령어로 실행할 분기를 결정할 수 있으며, 이진 검색은 switch 문에 있는 case 수로 측정할 때 대수적 수의 비교만 수행한다.

일반적으로 이러한 최적화가 발생했는지 확인하는 유일한 방법은 컴파일러에서 생성된 어셈블리 언어 또는 기계어 출력을 살펴보는 것이다.

5. 장단점

Switch 문은 `if else if` 문보다 다음과 같은 장점이 있다고 여겨진다.


  • 디버깅이 더 쉽다. (코드에 중단점 설정 vs. 호출 테이블, 디버거에 조건부 중단점 기능이 없는 경우)[7]
  • 사람이 읽기 쉽다.[7]
  • 이해하기 쉬워 유지 관리가 쉽다.[7]
  • 고정된 깊이를 가진다. "if else if" 문의 시퀀스는 깊은 중첩을 생성하여 컴파일을 더 어렵게 만들 수 있다 (특히 자동으로 생성된 코드에서).[7]
  • 모든 값이 처리되었는지 확인하기 쉽다. 컴파일러는 일부 열거형 값이 처리되지 않은 경우 경고를 표시할 수 있다.[7]


또한, 최적화된 switch 문은 인덱싱된 분기 테이블을 사용하여 구현되기 때문에 `if else if` 문보다 훨씬 빠르게 실행될 수 있다.[7] 예를 들어, 단일 문자의 값을 기반으로 프로그램 흐름을 결정하는 것은 올바르게 구현될 경우 `if else if` 문보다 훨씬 효율적이며 명령어 경로 길이를 상당히 줄인다. 이러한 방식으로 구현될 때, switch 문은 본질적으로 완전 해시가 된다.[7]

제어 흐름 그래프 측면에서 switch 문은 두 개의 노드(입구 및 출구)와 각 옵션에 대한 하나의 에지로 구성된다. 반대로, "if...else if...else if" 문 시퀀스는 첫 번째 및 마지막 케이스를 제외한 모든 케이스에 대해 추가 노드와 해당 에지가 있다. 따라서 "if" 시퀀스에 대한 결과 제어 흐름 그래프는 더 많은 노드와 거의 두 배나 많은 에지를 가지며, 이는 유용한 정보를 추가하지 않는다. 그러나 if 문의 단순한 분기는 switch 문의 복잡한 분기보다 개별적으로 개념적으로 더 쉽다. 사이클로매틱 복잡도 측면에서, 이 두 옵션 모두 ''k''개의 케이스가 주어지면 ''k''−1만큼 증가한다.

6. 언어별 구현

대부분의 프로그래밍 언어에서 switch 문은 하나 또는 두 개의 키워드를 사용하여 여러 줄에 걸쳐 작성된다. 일반적인 구문은 다음과 같다.


  • `select` 키워드로 시작하며, switch 문의 '제어식' 또는 '제어 변수'라고 하는 표현식이 뒤따른다.
  • 일치하는 경우 실행할 문 시퀀스와 함께 실제 케이스(값)를 정의하는 줄이 이어진다.
  • 폴스루(fall through) 동작이 있는 언어에서는 일반적으로 `break` 문이 `case` 문을 종료한다.[4]
  • PL/I처럼 제어식이 선택 사항인 언어도 있다. 제어식이 없으면 각 대안은 부울 표현식이 포함된 `WHEN` 절로 시작하며, 해당 표현식이 참으로 평가되는 첫 번째 케이스에 대해 일치가 발생한다. 이는 Perl과 같은 일부 다른 언어의 if/then/elseif/else 구조와 유사하다.
  • Rexx와 같이 제어식이 허용되지 않는 언어도 있으며, 각 대안은 부울 표현식이 포함된 `WHEN` 절로 시작한다.


각 대안은 제어 변수가 일치할 수 있는 특정 값 또는 값 목록으로 시작하고, 제어가 해당 문 시퀀스로 goto하게 한다. 값은 일반적으로 콜론 또는 암시 화살표로 해당 문 시퀀스와 구분된다. 많은 언어에서 모든 케이스 앞에는 `case` 또는 `when`과 같은 키워드가 있어야 한다.

`default`, `otherwise` 또는 `else` 키워드로 지정된 선택적 기본 케이스도 일반적으로 허용된다. 이는 다른 케이스가 제어식과 일치하지 않을 때 실행된다. C와 같은 일부 언어에서는 케이스가 일치하지 않고 `default`가 생략되면 `switch` 문이 아무것도 수행하지 않는다. PL/I와 같은 다른 언어에서는 오류가 발생한다.

파스칼 계열(Object Pascal, Modula, Oberon, Ada 등), PL/I, 파스칼의 영향을 받은 포트란과 BASIC 방언의 현대적 형태, 대부분의 함수형 언어 등에서는 일치하는 블록만 실행하고, switch 문의 끝에서 실행이 계속된다. 여러 값이 동일한 코드를 실행할 수 있도록, 파스칼형 언어는 쉼표로 구분된 목록, 범위 또는 조합 형태로 제공되는 케이스당 여러 개의 값을 허용한다.

C 언어에서 파생된 언어와 계산된 GOTO의 영향을 받은 언어는 폴스루 기능을 특징으로 한다. 제어는 일치하는 케이스로 이동한 다음 소스 텍스트의 '다음' 케이스와 관련된 문으로 실행이 계속된다("폴스루"). 특수 구문 없이 여러 값이 동일한 지점과 일치할 수 있다. 빈 본문과 함께 나열되기만 하면 된다. 값은 케이스 본문의 코드로 특수 조건을 사용할 수 있다. 폴스루는 일반적으로 일치하는 본문의 끝에 있는 `break` 키워드로 방지되지만, 프로그래머가 `break` 문을 삽입하는 것을 잊으면 의도하지 않은 폴스루로 인해 버그가 발생할 수 있다.[4] 많은 사람들은 이를 언어의 문제점으로 보고 일부 린트 도구에서 경고한다. 구문적으로 케이스는 블록이 아닌 레이블로 해석되며 switch 및 break 문은 명시적으로 제어 흐름을 변경한다. 자바스크립트와 같이 C의 영향을 받은 일부 언어는 기본 폴스루를 유지하고 다른 언어는 폴스루를 제거하거나 특별한 경우에만 허용한다. C#는 모든 블록이 비어 있지 않은 한 `break` 또는 `return`으로 종료되어야 한다.

펄은 기본적으로 폴스루하지 않지만 `continue` 키워드를 사용하여 명시적으로 폴스루할 수 있다. 배시는 `;;`로 종료될 때 기본적으로 폴스루하지 않지만 `;&` 또는 `;;&`를 사용하여 폴스루를 허용한다.[5]

많은 언어에서 `switch` 블록 내부의 표현식을 런타임에 평가한다. 이는 특정 컴파일러 최적화를 금지하므로, 동적 및 스크립트 언어에서 더 흔하게 사용된다.

어셈블리 언어의 switch 문 예시는 다음과 같다.

```nasm

switch:

cmp ah, 00h

je a

cmp ah, 01h

je b

jmp swtend ; 일치하는 사례 없음 또는 "default" 코드

a:

push ah

mov al, 'a'

mov ah, 0Eh

mov bh, 00h

int 10h

pop ah

jmp swtend ; "break"와 동일

b:

push ah

mov al, 'b'

mov ah, 0Eh

mov bh, 00h

int 10h

pop ah

jmp swtend ; "break"와 동일

...

swtend:

```

구조적 프로그래밍된 BASIC에서는 `Select Case` 문이 존재하며, 문자열 또는 정수를 대상으로 할 수 있다. C 등과 달리, 각 `Case`는 레이블이 아니고 `Select` 문은 폴스루가 아니다.

Perl에서는 perl-5.8 이후부터 `use Switch`를 사용하여 switch case 문을 사용할 수 있다.

루비에서는 `case` 식을 사용하여 다중 분기를 수행할 수 있다. 폴스루는 없으며, 레이블과 조건 값은 `===` 연산자로 비교된다.[18]

미디어위키 계열의 에서는 파서 함수를 사용하여 다중 분기를 수행할 수 있다. C나 C#과 같은 언어에서의 return문이나 break문은 없다.

많은 표 계산 소프트웨어에서는 `CHOOSE` 함수의 확장으로 `SWITCH` 함수를 사용할 수 있다. 예를 들어 Microsoft Excel 2019 이후 (Office 365 포함)[20], LibreOffice Calc 5.2 이후[21], Google 스프레드시트[22]에서 지원된다. 구문은 다음과 같다.

`SWITCH(식, 케이스1, 결과 값1[, 케이스2, 결과 값2, ...][, 기본 결과 값])`

검사되는 임의의 유효한 값.
케이스식에 대해 비교되는 케이스.
결과 값케이스가 식과 일치할 때 반환되는 값.
기본 결과 값마지막 매개변수로 지정되는 선택적 값으로, 어떤 케이스도 식과 일치하지 않는 경우 반환된다.



만약 식이 어떤 케이스와도 일치하지 않고 기본 결과 값이 주어지지 않은 경우, `#N/A` 오류가 반환된다.

C, C++, C#, Java, PHP, Python, Ruby, Go, BASIC 등 다양한 언어별 구현 방식은 하위 섹션에서 자세히 설명하고 있다.

6. 1. C/C++

C/C++에서 `switch` 문은 다음과 같은 구문을 갖는다.[1]

```c

switch (제어식) {

case 값1:

문장

문장

………

break;

case 값2:

문장

문장

………

break;

default:

문장

}

```

`case` 레이블은 여러 개를 사용할 수 있다. `case` 레이블의 "값"은 컴파일 시점에 결정되는 정수 상수식이어야 한다.[1]

`switch` 문은 다음과 같은 순서로 실행된다.[1]

1. 제어식을 평가하여 정수 값을 얻는다.

2. 해당 정수 값이 `case`에서 지정된 값과 일치하면, 해당 `case`에 이어지는 문장으로 이동한다.

3. 어느 `case`에서도 지정되지 않은 경우에는 `default`에 이어지는 문장으로 이동한다.

4. 만약 `default`가 없다면, 아무것도 실행하지 않고 `switch` 문을 빠져나간다.

`case`는 레이블일 뿐이며, `switch` 문을 빠져나가게 하는 기능은 없다. 일반적으로 다음 `case`가 나타나기 직전에 break 문을 둔다. 이 규칙을 폴스루(fall through)라고 하며, 제어 흐름이 합류하는 동작을 원하는 경우에 편리하지만, `break` 문을 잊어서 생기는 버그나 루프를 빠져나가는 `break`와 착각하여 발생하는 버그의 원인이 되기도 한다.[1]

린트에서는 의도적인 폴스루임을 나타내는 `/* FALLTHROUGH */` 등의 주석이 없으면 경고를 표시한다. C#처럼 폴스루를 막는 대책을 마련한 언어도 있다.[1]

`switch` 문은 if 문을 나열하여 동일한 동작을 구현할 수 있지만, `if` 문에서는 비교 대상의 "값"이 정수 상수식일 필요가 없다는 점에서 `switch` 문보다 유연하다.[1]

`default`는 마지막에 작성하는 경우가 많지만, 반드시 마지막일 필요는 없다.[1]

`switch`는 do-while 문과 조합하여 사용할 수도 있다. Duff's device에서 이러한 방식을 사용한다.[1]

6. 2. C#

C#에서의 switch 문은 C 언어와 유사한 형태를 보이지만, 폴스루(fall-through)에 대한 동작은 다르다.[17]

```csharp

switch (식)

{

case 0:

case 1:

// 식이 0 또는 1일 때 실행

System.Console.WriteLine("Case 0 or 1.");

return 1;

case 2:

System.Console.WriteLine("Case 2.");

goto case 3: // case 3도 실행

case 3:

System.Console.WriteLine("Case 3.");

break;

default:

System.Console.WriteLine("Default.");

break; // 이 부분의 break도 생략 불가

}

```

C#에서는 case 레이블이 문에 속하는 것으로 취급되지만, 하나의 문에 여러 개의 case 레이블을 붙일 수 있다. 또한 C 언어와 같은 폴스루는 금지되어 있으며, 다음 case 레이블이 붙은 문, 또는 switch 블록의 끝에, 일반적인 제어 흐름으로는 도달해서는 안 된다. 즉, break로 switch 문을 빠져나가거나, return으로 함수 전체를 빠져나가거나, 예외를 발생시키거나, 무한 루프로 더 이상 진행하지 않는 등의 방법을 사용해야 한다.[17] `goto case`를 사용하면 C 언어에서 폴스루를 사용하여 작성할 수 있었던 제어의 합류를 작성할 수 있다.

C나 C++에서는 switch 문의 제어식에 정수형 식, 그리고 case 레이블에는 정수 상수식만 사용할 수 있지만, C#에서는 각각 문자열형 및 문자열 리터럴도 사용할 수 있다. 또한, 정수형 또는 정수형에 준하는 값 형식의 null 허용 형식 `System.Nullable`도 사용할 수 있다.

C# 7.0 이후에는 형식 switch를 사용할 수 있다.

```csharp

// C# 7.0 이후

switch (obj)

{

case int num when num < 0:

Console.WriteLine($"obj는 음의 32bit 정수{num}입니다.");

break;

case string str when str.StartsWith("H"):

Console.WriteLine($"obj는 H로 시작하는 문자열{str}입니다.");

break;

case string str:

Console.WriteLine($"obj는 문자열{str}입니다.");

break;

default:

Console.WriteLine("obj는 예상치 못한 형식 또는 값입니다.");

break;

}

6. 3. Java

Java SE 12 (2019년 3월 19일)에 '스위치 표현식'이 미리 보기 기능으로 도입되었다. 이를 통해 스위치 표현식을 사용하여 값을 반환할 수 있다. 또한 `case L ->` 와 같은 새로운 형태의 case 레이블이 추가되었는데, 여기서 `->` 우측에는 단일 표현식이 온다. 이는 폴스루(fall through)를 방지하고 case가 완전하도록 강제한다.[8][9][10] Java SE 13에서는 `yield` 문이 도입되었고, Java SE 14에서는 스위치 표현식이 표준 언어 기능이 되었다.

아래는 스위치 표현식 사용 예시이다.

```java

int ndays = switch (month) {

case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;

case APR, JUN, SEP, NOV -> 30;

case FEB -> {

if (year % 400 == 0) yield 29;

else if (year % 100 == 0) yield 28;

else if (year % 4 == 0) yield 29;

else yield 28;

}

};

6. 4. PHP

PHP에서는 C#과 마찬가지로 문자열에도 switch 문을 적용할 수 있다.

```php

switch (str) {

case "ABC":

문A;

break;

case "XYZ":

문B;

break;

case "123":

문C;

break;

default:

문D;

break;

}

```

PHP의 switch 문에서는 비교가 `===` 연산자가 아닌 `==` 연산자로 수행된다. 따라서 모호한 일치로 인해 개발자가 예상치 못한 동작을 할 수 있다.[18]

PHP나 JavaScript 등 case의 표현식이 상수일 필요가 없는 언어의 경우 `switch(true)`로 작성하여 조건식 기반 switch 문을 구현할 수 있다.

```php

switch (true) {

case ($x == 'hello'):

foo();

break;

case ($z == 'howdy'): break;

}

switch (5) {

case $x: break;

case $y: break;

}

6. 5. Python

Python 3.10.6 버전부터 PEP 634-636이 채택되어 `match` 및 `case` 키워드가 추가되었다.[11][12][13][14] 다른 언어와 달리 Python은 폴스루(fallthrough) 동작을 보이지 않는다.

```python

letter = input("문자 하나를 입력하세요: ").strip()[0].casefold() # 입력의 첫 번째 공백이 아닌 문자, 소문자

match letter:

case 'a' | 'e' | 'i' | 'o' | 'u': # if 문의 조건과 달리, 'or' 키워드는 여기서 case를 구분하기 위해 사용할 수 없다.

print(f"문자 {letter}는 모음입니다!")

case 'y':

print(f"문자 {letter}는 모음일 수 있습니다.")

case _: # `case _`는 C 등에서 `default`와 동일하다.

print(f"문자 {letter}는 모음이 아닙니다!")

6. 6. Ruby

루비에서는 `case` 식을 사용하여 다중 분기를 수행할 수 있다. 폴스루(fall-through)는 없으며, 레이블과 조건 값은 `===` 연산자로 비교된다.[18] 이 연산자는 오버로드가 가능하여 클래스에 따른 일치 판정을 할 수 있다. 루비 클래스 라이브러리 내에서 정규 표현식 일치 판정,[19] 범위 객체의 범위 내 여부 판정, 객체의 특정 클래스 소속 여부 판정 등 다양한 정의가 이루어져 있다.

`case` 식은 값을 반환하여 변수에 할당할 수 있으며, 매개변수 없이 `else if` 문처럼 사용할 수도 있다.

```ruby

catfood =

case

when cat.age <= 1

junior

when cat.age > 10

senior

else

normal

end

```

Ruby[18]SQL에서는 `switch`에 해당하는 문 뒤의 표현식이 필수가 아니다. 생략할 경우 `when` 절에서 처음으로 참이 되는 부분을 실행한다.

6. 7. Go

Go에서는 `case`에 복수의 값을 지정할 수 있다. `fallthrough` 문을 두면 폴스루가 된다.[1]

6. 8. BASIC

구조적 프로그래밍된 BASIC에서는 `Select Case` 문이 존재하는 경우가 많다. 이 문을 통해 문자열 또는 정수를 대상으로 할 수 있다.

C와는 달리, 각 `Case`는 레이블이 아니고 `Select` 문은 폴스루(fall through)가 아니다.

6. 9. 기타 언어

PHP에서는 C#과 마찬가지로 문자열에도 switch 문을 적용할 수 있다.[20] PHP의 switch 문에서는 비교가 `===` 연산자가 아닌 `==` 연산자로 수행된다. 따라서 모호한 일치로 인해 개발자가 예상치 못한 동작을 할 수 있다.

Perl에서는 perl-5.8 이후부터 `use Switch`를 사용하여 switch case 문을 사용할 수 있게 되었다. 이전 버전의 Perl에 관해서는 Perl 부속 문서 perlsyn 문서의 Basic BLOCKs and Switch Statements 절에 형식의 예가 쓰여 있다.

미디어위키 계열의 에서는 파서 함수를 사용하여 다중 분기를 수행할 수 있다. 일대일 분기 처리 외에도 여러 값에 대해 동일한 처리를 정의하는 일종의 폴스루(fall-through)도 구현할 수 있다. 그러나 C나 C#과 같은 언어에서의 return문이나 break문이 없다. 따라서 처리 도중에 Switch 문을 빠져나가려면 if 등의 조건문으로 처리를 감싸서 실행되지 않도록 제어해야 한다. 자세한 내용은 Help:조건문#switch 항목을 참조하라.

많은 표 계산 소프트웨어에서는 `CHOOSE` 함수의 확장으로 `SWITCH` 함수를 사용할 수 있다. 예를 들어 Microsoft Excel 2019 이후 (Office 365 포함)[20], LibreOffice Calc 5.2 이후[21], Google 스프레드시트[22]에서 지원된다. 지정 가능한 케이스와 결과 값의 쌍의 상한은 환경에 따라 다르지만, 대략 다음과 같은 구문이다.

`SWITCH(식, 케이스1, 결과 값1[, 케이스2, 결과 값2, ...][, 기본 결과 값])`

검사되는 임의의 유효한 값.
케이스식에 대해 비교되는 케이스.
결과 값케이스가 식과 일치할 때 반환되는 값.
기본 결과 값마지막 매개변수로 지정되는 선택적 값으로, 어떤 케이스도 식과 일치하지 않는 경우 반환된다.



만약 식이 어떤 케이스와도 일치하지 않고, 게다가 기본 결과 값이 주어지지 않은 경우, `#N/A` 오류가 반환된다.

7. 대안


  • 대상 값을 하나씩 검사하는 ''if-else'' 조건문을 사용할 수 있다. 폴스루(fallthrough) 동작은 ''else'' 절이 없는 ''if'' 조건문으로 구현할 수 있다.
  • 룩업 테이블을 활용할 수 있는데, case 값을 키로, case 문 아래 부분을 값으로 사용한다.

::(일부 언어에서는 실제 데이터 유형만 룩업 테이블의 값으로 허용된다. 다른 언어에서는 함수를 룩업 테이블 값으로 할당하여 switch 문과 같은 유연성을 확보할 수 있다. 자세한 내용은 제어 테이블 문서를 참조.)

::루아는 case/switch 문을 지원하지 않는다.[15] 내장 switch 문이 없는 루아에서 switch 문을 구현하는 한 가지 방법은 이 룩업 기술을 이용하는 것이다.[15]

::룩업 테이블은 최적화되지 않은 switch 문보다 효율적일 수 있다. 많은 언어가 테이블 룩업을 최적화할 수 있지만, switch 문은 값의 범위가 작고 간격이 적은 경우에만 최적화되기 때문이다. 그러나 최적화되지 않은 비-이진 탐색 룩업은 최적화되지 않은 switch나 여러 개의 ''if-else'' 문보다 느리다.

  • 제어 테이블(단순 룩업 테이블로 구현 가능)은 여러 입력에 대한 조건을 수용하도록 사용자 정의할 수 있으며, 일반적으로 switch보다 시각적으로 간결하다.
  • 많은 함수형 프로그래밍 언어에서 switch와 유사한 기능을 구현하는 데 패턴 매칭을 사용한다.

참조

[1] 서적 C# in Depth Manning 2019-03-23
[2] 서적 "Effective Java: Programming Language Guide" Addison-Wesley
[3] 문서 Definition by cases Kleene 1952
[4] 서적 "Expert C Programming: Deep C Secrets" Prentice Hall, Eaglewood Cliffs
[5] 뉴스 since version 4.0 http://git.savannah.[...] 2009
[6] 웹사이트 From Switch Statement Down to Machine Code https://web.archive.[...] Vlad Lazarenko
[7] 서적 Optimized C++ O'Reilly Media 2016-04-27
[8] 웹사이트 JEP 325: Switch Expressions (Preview) https://openjdk.java[...] 2021-04-28
[9] 웹사이트 JEP 354: Switch Expressions (Second Preview) https://openjdk.java[...] 2021-04-28
[10] 웹사이트 JEP 361: Switch Expressions https://openjdk.java[...] 2021-04-28
[11] 웹사이트 What's New In Python 3.10 https://docs.python.[...] 2022-08-19
[12] 웹사이트 PEP 634 – Structural Pattern Matching: Specification https://peps.python.[...] 2020-09-12
[13] 웹사이트 PEP 635 – Structural Pattern Matching: Motivation and Rationale https://peps.python.[...] 2020-09-12
[14] 웹사이트 PEP 636 – Structural Pattern Matching: Tutorial https://peps.python.[...] 2022-08-19
[15] 웹사이트 Switch statement in Lua http://lua-users.org[...]
[16] 웹사이트 パターン - is および switch 式を使ったパターン マッチング。 - C# | Microsoft Learn https://learn.micros[...]
[17] 웹사이트 switch(C#リファレンス) http://msdn.microsof[...] 2014-05-30
[18] 웹사이트 Ruby 1.9.3マニュアル - 制御構造 http://docs.ruby-lan[...] 2014-03-03
[19] 웹사이트 Ruby 1.9.3マニュアル - class Regexp http://docs.ruby-lan[...] 2014-03-03
[20] 웹사이트 SWITCH function - Microsoft Support https://support.micr[...]
[21] 웹사이트 SWITCH function | LibreOffice Help https://help.libreof[...]
[22] 웹사이트 SWITCH - Google ドキュメント エディタ ヘルプ https://support.goog[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com