return 은 값을 돌려주면서 메서드를 끝낸다
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을 만나야 합니다. 컴파일러가 확인합니다.