言語によって振る舞いが異なるようなのでメモ。
C#
using System;
using System.Collections.Generic;
class Program {
static IEnumerable<string> Three() {
yield return "one";
yield return "two";
yield return "three";
}
static void Main() {
var co = Three();
Console.WriteLine("1");
foreach (var x in co)
Console.WriteLine(x);
Console.WriteLine("2");
foreach (var x in co)
Console.WriteLine(x);
}
}
実行結果:
1
one
two
three
2
one
two
three
JavaScript(Node)
"use strict"
function* three() {
yield "one";
yield "two";
yield "three";
}
function main() {
var co = three();
console.log("1");
for (let x of co)
console.log(x);
console.log("2");
for (let x of co)
console.log(x);
}
main();
実行結果:
1
one
two
three
2
Julia
function three()
produce("one")
produce("two")
produce("three")
end
function main()
co = @task three()
println("1")
for x = co
println(x)
end
println("2")
for x = co
println(x)
end
end
main()
実行結果:
1
one
two
three
2
Lua
function three()
coroutine.yield("one")
coroutine.yield("two")
coroutine.yield("three")
end
function main()
co = coroutine.wrap(three)
print("1")
for x in co do
print(x)
end
print("2")
for x in co do
print(x)
end
end
main()
実行結果:
1
one
two
three
2
lua: a.lua:17: cannot resume dead coroutine
stack traceback:
[C]: in function 'for iterator'
a.lua:17: in function 'main'
a.lua:23: in main chunk
[C]: in ?
Python
def three():
yield "one"
yield "two"
yield "three"
def main():
co = three()
print("1")
for x in co:
print(x)
print("2")
for x in co:
print(x)
main()
実行結果:
1
one
two
three
2
追記:
下記のような方法もあります。
class three:
def __iter__(self):
yield "one"
yield "two"
yield "three"
実行結果:
1
one
two
three
2
one
two
three
Ruby
def three
Enumerator.new do |y|
y << "one"
y << "two"
y << "three"
end
end
def main
co = three()
puts "1"
for x in co
puts x
end
puts "2"
for x in co
puts x
end
end
main
実行結果
1
one
two
three
2
one
two
three
まとめ
C# と Ruby では、for 文で同じコルーチンを使い回すと要素の先頭から取り出されるような振る舞いとなった。JavaScript(Node), Julia, Lua, Python では、コルーチンは使い切りで使い回しができないような振る舞いとなった。
各言語のバージョン
- C#: Mono JIT compiler version 4.2.1
- Node v5.1.0
- julia version 0.4.0
- Lua 5.3.0
- Python 3.4.0 (v3.4.0:04f714765c13, Mar 15 2014, 23:02:41)
- ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]