Python의 생성기와 코루틴을 C#으로 표현하면.
요즘 이 책을 재미있게 보고 있습니다. ^^
Programming Insight 파이썬 완벽 가이드
; http://www.yes24.com/24/goods/6694057
그중에서 코루틴에 대한 이야기가 재미있습니다. 언어 간의 비교를 해보면 이해도를 높일 수 있고 서로 간의 장단점도 쉽게 파악이 되지요. ^^ 그래서 C#으로 한번 표현을 해봤습니다.
우선, 파이썬에서 yield를 이용한 구문 중에서 코루틴보다 간단한 생성기(generator)에 대한 예제를 먼저 보겠습니다.
def countdown(n):
while n > 0:
yield n
n -= 1
for i in countdown(5):
print i
이건 좀 쉽습니다. ^^ C#에서도 역시 yield 키워드를 이용해서 다음과 같이 만들어 볼 수 있습니다.
class Program
{
static void Main(string[] args)
{
Program inst = new Program();
foreach (var item in inst.CountDown(5))
{
Console.WriteLine(item);
}
}
IEnumerable<int> CountDown(int maxValue)
{
while (maxValue > 0)
{
yield return maxValue --;
}
}
}
부수적인 코드들이 들어갈 뿐 구조상으로 보면 파이썬의 표현과 거의 1:1 매핑이 됩니다.
다음으로 파이썬의 코루틴입니다.
def print_matches(matchtext):
print "Looking for", matchtext
while True:
line = (yield)
if matchtext in line:
print line
matcher = print_matches("python")
matcher.next()
matcher.send("Hello World")
matcher.send("python is cool")
matcher.close()
// 출력 결과
Looking for python
python is cool
대강 어떤 식인지 눈에 보이시죠? matcher.send의 인자로 입력된 것이 print_matches 함수의 (yield) 문의 결과로 반환되어 식이 평가되고 있는 것입니다.
요건 C#으로 옮기기에 그다지 멋있게 되지는 않지만, 다음과 같이 가능은 합니다.
class Program
{
static void Main(string[] args)
{
Program inst = new Program();
inst.print_matches("python");
inst.send("Hello World");
inst.send("python is cool");
}
string _matchText;
string _message;
IEnumerator<int> iter;
void print_matches(string matchtext)
{
Console.WriteLine("Looking for: " + matchtext);
_matchText = matchtext;
iter = iterator().GetEnumerator();
iter.MoveNext();
}
public void send(string message)
{
_message = message;
iter.MoveNext();
}
IEnumerable<int> iterator()
{
yield return 0;
while (true)
{
if (_matchText.IndexOf(_message) == -1)
{
yield return 0;
}
Console.WriteLine(_message);
yield return 1;
}
}
}
음... 다소 억지스러운가요? ^^ 그나저나... 파이썬이라... 마음에 듭니다. ^^
(
예제 코드는 첨부해 두었습니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]