switch 는 조건이 아니라 값을 본다
Esc

    switch 는 조건이 아니라 값을 본다

    –C#기초

    앞 글의 else if 사슬로 요일을 찍어 보겠습니다.

    if (day == 1)
    {
        Console.WriteLine("월요일");
    }
    else if (day == 2)
    {
        Console.WriteLine("화요일");
    }
    else if (day == 3)
    {
        Console.WriteLine("수요일");
    }

    일곱 개까지 이어집니다. 그런데 자세히 보면 조건이 전부 같은 모양입니다. 변수도 day 하나, 연산자도 == 하나. 바뀌는 것은 오른쪽 값뿐입니다.

    묻는 것이 “이 값이 무엇인가” 하나뿐일 때 쓰는 문법이 switch 입니다.

    switch 는 이렇게 생겼다

    switch (값) { case 후보: 실행할 코드 break; default: 실행할 코드 break; } 맞춰 볼 값 하나 값이 이것과 같으면 여기로 뛴다 여기서 switch 를 빠져나온다 맞는 후보가 하나도 없을 때
    맞춰 볼 값 하나, 후보 목록, 그리고 나가는 문.

    if 는 괄호 안에 조건이 들어갔습니다. switch 는 괄호 안에 값이 들어갑니다. day > 3 같은 것을 넣을 수 없습니다. 참거짓을 묻는 자리가 아니라 “이 값이 무엇이냐”를 묻는 자리이기 때문입니다.

    맞는 자리로 바로 뛴다

    else if 사슬은 위에서부터 조건을 하나씩 검사했습니다. switch 는 그럴 필요가 없습니다. 물어보는 것이 “같은 값인가” 하나뿐이라 컴파일러가 후보를 미리 정리해 둘 수 있기 때문입니다. 후보가 몇 개 안 되면 그냥 비교하지만, 많아지면 표를 만들어 두고 곧장 그 자리로 보냅니다.

    후보가 늘어나도 찾는 비용이 그만큼 늘지 않는다는 것이 switch 의 성질입니다. else if 는 마지막 후보에 걸리려면 앞의 조건을 전부 지나가야 합니다.

    break 는 선택이 아니다

    C# 은 case 아래 코드가 있으면 반드시 break 같은 것으로 닫아야 합니다. 안 닫으면 컴파일이 안 됩니다.

    switch (day)
    {
        case 1:
            Console.WriteLine("월요일");
            // break 가 없으면 컴파일 에러
        case 2:
            Console.WriteLine("화요일");
            break;
    }

    C나 Java에서는 이게 그냥 통과합니다. 그리고 break 를 빠뜨리면 아래 case 로 그대로 흘러내려서 월요일과 화요일이 같이 찍힙니다. 찾기 어려운 종류의 버그였고, C# 은 이걸 문법으로 막았습니다.

    여러 값을 같은 코드로 처리하고 싶을 때는 case 를 붙여서 씁니다. 이건 사이에 코드가 없으니 허용됩니다.

    switch (day)
    {
        case 6:
        case 7:
            Console.WriteLine("주말");
            break;
        default:
            Console.WriteLine("평일");
            break;
    }

    default 는 else 다

    default 는 else 와 같은 자리입니다. 어느 후보에도 안 걸린 값이 전부 여기로 옵니다.

    else 와 마찬가지로 필수가 아닙니다. 안 쓰면 맞는 case 가 없을 때 switch 는 아무 일도 하지 않고 지나갑니다. 에러도 경고도 없습니다.

    후보를 다 적었다고 생각할 때가 위험합니다. 요일이 1부터 7이니 case 를 일곱 개 적으면 끝이라고 생각하지만, day 에 0이나 100이 들어올 수 있다면 그때는 조용히 아무 일도 안 일어납니다. default 는 “그럴 리 없다”를 눈에 보이게 적어두는 자리입니다.

    범위는 if, 목록은 switch

    둘 중 무엇을 쓸지는 조건의 모양이 정합니다.

    if / else if switch
    조건 형태 어떤 조건식이든 하나의 값과 같은지만
    범위 비교 age >= 19 가능 불가능
    복합 조건 &&, || 조합 가능 불가능
    후보가 많을 때 길어지고 읽기 어렵다 한눈에 보인다
    대표 예 가격, 등급, 자격 판정 요일, 메뉴 번호, 상태 값

    앞 글의 등급 코드는 switch 로 못 바꿉니다. score >= 90 은 값이 아니라 범위니까요. 반대로 요일 출력은 else if 로 쓸 수는 있지만, 같은 질문을 일곱 번 반복해서 적게 됩니다.

    고를 수 있는 후보가 정해져 있으면 switch, 재야 하면 if 입니다.

    switch 괄호에 넣을 수 있는 것은 값이 딱 떨어지는 타입입니다. 정수, char, string, bool, 그리고 뒤에 나올 enum. double 처럼 같은지를 따지기 어려운 타입은 여기 어울리지 않습니다. 앞에서 본 대로 0.1 + 0.2 == 0.3 이 거짓인 타입으로 후보를 맞출 수는 없습니다.

    정리

    • 묻는 것이 “이 값이 무엇인가” 하나뿐일 때 쓰는 문법이 switch 입니다.
    • if 괄호에는 조건이, switch 괄호에는 값이 들어갑니다. 범위 비교는 못 씁니다.
    • 맞는 case 로 곧장 갑니다. 후보가 늘어도 찾는 비용이 그만큼 늘지 않습니다.
    • case 아래 코드가 있으면 break 로 닫아야 합니다. 안 닫으면 컴파일 에러입니다.
    • 값 여러 개를 같이 처리하려면 case 를 사이에 코드 없이 붙여 씁니다.
    • default 는 else 자리입니다. 없으면 아무 일도 안 하고 지나갑니다.