Go의 switch
작성 규칙은 다음과 같다.
SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
이 중 ExprSwitchStmt 규칙은 다음과 같다.
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" StatementList .
ExprSwitchCase = "case" ExpressionList | "default" .
자세히 보면 switch
뒤에도, case
뒤에도 단순히 Expression이 올 수 있다. C/C++, Java에 익숙한 개발자라면 단서를 기대할 것이다.
C의 switch
를 보자.
switch (expression)
{
case constant_expression:
//statement
break;
default:
//statement
}
- The expression used in a switch statement must have an integral or enumerated type, or be of a class type in which the class has a single conversion function to an integral or enumerated type.
- The constant-expression for a case must be the same data type as the variable in the switch, and it must be a constant or a literal.
Java는 다음과 같다.
switch (expression) {
case value:
//statement
break;
default:
//statement
}
- The expression used in a switch statement can only be integers, convertable integers (byte, short, char), strings and enums.
- The value for a case must be the same data type as the variable in the switch and it must be a constant or a literal.
JDK7 이전의 옛날 얘기는 하지 말고, Java는 문자열도 switch
에 쓸 수 있다는 점을 제외하면 그놈이 그놈이다. C가 버전 1.0이라면 Java는 버전 1.1 정도라고나 할까.
Go switch
버전을 몇으로 해야 할지는 이견이 있겠으나 최소한 1.2, 1.3 수준이 아닌 것은 확실하다. 여기에 이 글에서는 살펴보지 않은 TypeSwitchStmt 용법까지 포함하면 Major 버전을 몇 단계는 올려야 한다. 그래서 봉인해제다.
타입 조건 해제
Go는 숫자형이 아니어도, 문자열이 아니어도 switch
에 사용할 수 있다. 안타깝게도 아직 다양한 타입에 대해서는 다루지 않았으니 여기서는 그냥 넘어가도록 하자. 사실 다양한 타입을 쓸 수 있다는 것은 그리 특별한 것은 아니다.
상수 조건 해제
가장 눈에 띄는 것은 case
뒤에 오는 Expression이 상수일 필요가 없다는 점일 것이다. 즉, 다음과 같은 코드도 가능하다.
var c = 3
var c1, c2 = 1, 2
switch c {
case c1:
fmt.Println("c1")
case c2:
fmt.Println("c2")
case c1 + c2:
fmt.Println("c1 + c2")
}
case
뒤 Expression이 상수일 필요가 없다는 사실은 예상보다 많은 코드 다양성을 보장한다. 예를 들어, C나 Java로 testFunc()
의 반환값이 1일 때와 그렇지 않을 때 다른 문자열을 출력하는 코드를 switch
로 작성한다고 가정해 보자.1
// c code
switch (testFunc())
{
case 1:
printf("1\n");
default:
printf("default\n")
}
그런데 Go는 하늘과 땅을 뒤집을 수도 있다.
// go code
switch 1 {
case testFunc():
fmt.Println("1")
default:
fmt.Println("default")
}
Go는 switch
뒤 Expression을 생략할 수도 있다. 생략한 경우 true
가 있는 것으로 가정한다. 즉, 다음 두 switch
코드는 같은 의미이다.
switch { /* */ }
switch true { /* */ }
switch
뒤 Expression이 true
이니 case
뒤 Expression은 참인 코드가 오면 된다.
switch {
case 1 > 2:
// statement
case 1 = 2:
// statement
case 1 < 2:
// statement
}
-
물론 이런 코드를
switch
로 작성하지는 않는다. ↩︎