return 은 값을 돌려주면서 메서드를 끝낸다
Esc

    return 은 값을 돌려주면서 메서드를 끝낸다

    –C#기초

    return 이 값을 돌려준다는 것은 앞에서 봤습니다. 그런데 하는 일이 하나 더 있습니다.

    int Test()
    {
        return 1;
        Console.WriteLine("여기는?");    // 실행되지 않습니다
    }

    return 아래는 실행되지 않습니다. 값을 돌려주는 동시에 메서드를 끝냅니다.

    위 코드는 사실 컴파일러가 경고를 줍니다. 닿을 수 없는 코드라고요. 앞에서 else if 순서를 잘못 써서 죽은 코드가 생겼을 때는 아무 말도 없었는데, 이건 알려 줍니다. 문장이 그 자리에 있다는 것만으로 확실히 잘못이니까요.

    return 은 돌려주기와 끝내기, 두 가지를 같이 합니다.

    반복문의 break 와 닮았고 다르다

    앞에서 break 는 반복문을 끝낸다고 했습니다. return 은 메서드 전체를 끝냅니다. 그래서 반복문 안에서 return 하면 반복문도 같이 끝납니다.

    int FindIndex(List<int> nums, int target)
    {
        for (int i = 0; i < nums.Count; i++)
        {
            if (nums[i] == target)
            {
                return i;       // 찾았으면 여기서 끝
            }
        }
    
        return -1;              // 다 돌았는데 없으면
    }

    찾는 순간 나갑니다. 뒤를 더 볼 이유가 없으니까요. break 로 반복문만 빠져나온 다음 아래에서 다시 판단하는 것보다 짧습니다.

    못 찾았을 때 -1 을 돌려주는 것은 관습입니다. 인덱스는 0 이상이니 -1 은 “없다” 는 뜻으로만 쓸 수 있습니다.

    void 도 return 할 수 있다

    돌려줄 값이 없어도 끝내기 용으로 쓸 수 있습니다.

    void PrintName(string name)
    {
        if (name == "")
        {
            return;        // 값 없이, 여기서 끝
        }
    
        Console.WriteLine(name);
    }

    return; 뒤에 아무것도 안 적습니다. 돌려줄 것이 없으니까요. “더 할 일이 없으니 나간다” 는 뜻만 남습니다.

    일찍 나가면 중첩이 펴진다

    여기가 이 글의 요점입니다. 조건을 다 통과해야 하는 코드를 봅시다.

    void Order(User user, Item item)
    {
        if (user != null)
        {
            if (user.IsActive)
            {
                if (item.Stock > 0)
                {
                    if (user.Money >= item.Price)
                    {
                        Buy(user, item);
                    }
                    else
                    {
                        Console.WriteLine("잔액 부족");
                    }
                }
                else
                {
                    Console.WriteLine("품절");
                }
            }
            else
            {
                Console.WriteLine("정지된 계정");
            }
        }
    }

    읽기 어렵습니다. 진짜 하려던 일인 Buy 가 중괄호 네 겹 안에 있고, else 와 그 짝인 if 가 화면 위아래로 멀리 떨어져 있습니다.

    return 으로 뒤집으면 이렇게 됩니다.

    void Order(User user, Item item)
    {
        if (user == null) return;
    
        if (!user.IsActive)
        {
            Console.WriteLine("정지된 계정");
            return;
        }
    
        if (item.Stock <= 0)
        {
            Console.WriteLine("품절");
            return;
        }
    
        if (user.Money < item.Price)
        {
            Console.WriteLine("잔액 부족");
            return;
        }
    
        Buy(user, item);
    }

    하는 일은 똑같습니다. 달라진 것은 조건을 뒤집고 안 되는 경우를 먼저 내보낸 것입니다.

    읽기가 달라집니다.

    • 들여쓰기가 한 겹입니다. 옆으로 밀리지 않습니다.
    • 조건과 그때 할 일이 붙어 있습니다. 멀리 있는 else 를 찾아갈 필요가 없습니다.
    • 마지막 줄이 진짜 하려던 일입니다. 위는 전부 걸러내는 과정입니다.
    • 조건을 하나 더 추가할 때 블록을 하나 더 파는 게 아니라 위에 한 덩어리를 붙입니다.

    이렇게 앞에서 걸러내고 나가는 if 를 가드 절 이라고 부릅니다. “여기를 통과했다면 이런 상태다” 를 보장하고 아래로 넘깁니다.

    짧으면 한 줄로 써도 된다

    앞에서 중괄호를 생략하지 말라고 했습니다. 그 이유는 나중에 한 줄을 더 붙일 때 if 에 안 딸린 채로 실행되기 때문이었습니다.

    가드 절은 예외로 봐도 됩니다.

    if (user == null) return;

    if 와 return 이 같은 줄에 있어서 아래에 뭘 붙여도 오해할 여지가 없습니다. 줄이 짧아서 한눈에 읽히고, 이런 줄이 서너 개 이어질 때 특히 깔끔합니다.

    다만 이건 이 모양일 때만입니다. 조건에 딸린 코드가 두 줄이 되는 순간 중괄호를 씁니다.

    모든 길에서 값을 돌려줘야 한다

    값을 돌려주는 메서드는 어느 길로 가든 return 을 만나야 합니다.

    int Grade(int score)
    {
        if (score >= 90)
        {
            return 100;
        }
        // 90 미만일 때 돌려줄 것이 없습니다 → 컴파일 에러
    }

    컴파일러가 막아 줍니다. if 만 있고 else 가 없으면 조건이 거짓일 때 빠져나갈 길이 없다는 것을 압니다.

    가드 절 방식이 여기서도 편합니다. 마지막에 기본값을 하나 두면 어느 길로 가든 반드시 하나는 만납니다.

    string Grade(int score)
    {
        if (score >= 90) return "A";
        if (score >= 80) return "B";
        if (score >= 70) return "C";
    
        return "F";
    }

    앞에서 본 else if 사슬과 같은 일을 합니다. return 이 그 자리에서 끝내 주니 else 를 안 써도 아래가 실행되지 않습니다.

    정리

    • return 은 값을 돌려주면서 메서드를 끝냅니다. 아래 코드는 실행되지 않습니다.
    • 반복문 안에서 return 하면 반복문도 같이 끝납니다. break 는 반복문만 끝냅니다.
    • void 메서드도 return; 으로 일찍 나갈 수 있습니다.
    • 안 되는 경우를 먼저 걸러 내보내면 중첩된 if 가 한 겹으로 펴집니다. 가드 절이라고 합니다.
    • 가드 절은 if (조건) return; 처럼 한 줄로 써도 됩니다. 같은 줄이라 오해할 여지가 없습니다.
    • 값을 돌려주는 메서드는 어느 길로 가든 return 을 만나야 합니다. 컴파일러가 확인합니다.