끝나지 않는 프로그래밍 일기

기존에는 out 매개변수를 통해 메서드를 호출하려면 먼저 변수를 넘겨주기 위해서 변수를 먼저 선언해야 했다. 보통 전달받는 메서드가 초기화하기 때문에, 이런 변수들을 넘겨주기 전에 초기화하지 않는다. 이와 같은 이유로, var를 사용해 변수를 선언하지 못하고 변수의 타입을 명시적으로 적어주어야만 했다.
public void PrintCoordinates(Point p)
{
    int x, y; // 미리 선언해야 함
    p.GetCoordinates(out x, out y);
    WriteLine($"({x}, {y})");
}

하지만 C# 7.0에 와서는 out 변수라는 기능이 추가되면서, 전달인자를 넘겨줄 때 변수를 선언할 수 있게 되었다.

public void PrintCoordinates(Point p)
{
    p.GetCoordinates(out int x, out int y);
    WriteLine($"({x}, {y})");
}

그리고 위의 예제를 보면 알겠지만, 위와 같이 메서드를 호출해도 다음 행에서 전달인자를 넘겨줄 때 선언한 변수를 그대로 사용할 수 있는 것을 볼 수 있다. 이는 out 변수는 자신을 둘러싸고 있는 블럭 내에서 사용이 가능하다는 뜻이다.

p.GetCoordinates(out var x, out var y);

이번에는 우리가 형식을 명시적으로 지정해줄 필요 없이, var로 변수를 선언하는 것을 볼 수 있다. 함수의 매개변수 정의를 통해 매개변수의 형식을 유추하게 되는 것이다.

public void PrintStars(string s)
{
    if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); }
    else { WriteLine("Cloudy - no stars tonight!"); }
}

out 매개변수는 Try..(TryParse(), TryGetValue(), ...) 패턴에서 주로 사용된다. 여기서 int.TryParse()는 문자열 s를 정수형으로 변환했는지에 대한 성공 여부를 Boolean 값으로 반환한다. 변환에 성공했다면 변수 i에는 변환된 값이 들어가게 된다.

p.GetCoordinates(out int x, out _); // x에만 관심이 있음

만약에 어떤 out 매개변수가 필요가 없는 경우, 이를 무시할 수 있도록 "out _"와 같이 작성할 수 있다. 예를 들어보면, 단순히 어떤 문자열이 정수로 변환이 될 수 있는지만 궁금한 경우 아래와 같이 작성해볼 수 있다.

string intString = "1234";
if (int.TryParse(intString, out _))
{ 
    // 정수가 맞음
}
else
{
    // 정수가 아님
}