봉인해제 switch

switch의 변신은 무죄

다시 switch 작성 규칙을 자세히 보면 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 수준이 아닌 것은 확실하다. 여기에 switch 조건문에서 살펴보지 않은 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
}

  1. 물론 이런 코드를 switch로 작성하지는 않는다. [return]