Rom*_*her 16 c# python iteration coroutine
所以我认为我理解c#yield return与pythons yield大致相同,我认为我理解.我认为编译器将一个函数转换为一个对象,该对象带有一个指向执行应该恢复的位置的指针,当对象的下一个值的请求运行到下一个yield时,它会更新指针的恢复执行位置并返回一个值.
在python中,它的工作方式类似于延迟评估,因为它根据需要生成值,但是一旦使用了值,如果不保存在另一个变量中,则可以使用gc.尝试迭代这样一个函数的结果两次返回一个空的iterable,除非你将它转换为一个列表.
恩.
def y():
list = [1,2,3,4]
for i in list:
yield str(i)
ys = y()
print "first ys:"
print ",".join(ys)
print "second ys:"
print ",".join(ys)
Run Code Online (Sandbox Code Playgroud)
输出
first ys:
1,2,3,4
second ys:
Run Code Online (Sandbox Code Playgroud)
直到最近我才认为c#也是如此,但在dotnetfiddle中尝试失败了.
http://dotnetfiddle.net/W5Cbv6
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static IEnumerable<string> Y()
{
var list = new List<string> {"1","2","3","4","5"};
foreach(var i in list)
{
yield return i;
}
}
public static void Main()
{
var ys = Y();
Console.WriteLine("first ys");
Console.WriteLine(string.Join(",", ys));
Console.WriteLine("second ys");
Console.WriteLine(string.Join(",", ys));
}
}
Run Code Online (Sandbox Code Playgroud)
输出
first ys
1,2,3,4,5
second ys
1,2,3,4,5
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?是缓存结果吗?它不可能是正确的,否则File.ReadLines会炸毁巨大的文件?它只是第二次从顶部重启功能吗?
注意:我对发电机和协同程序的一些术语有点不确定,所以我试图避免标记.
Ser*_*rvy 13
你很近.An IEnumerable是能够创建迭代器(an IEnumerator)的对象.的IEnumerator行为完全按照你所描述.
所以IEnumerable 生成生成器.
除非您不遗余力地生成在生成的迭代器之间共享的某种状态,IEnumerator否则对象不会相互影响,无论它们是来自对迭代器块的单独调用还是IEnumerator由其生成的另一个IEnumerable.
查看代码的每个部分后,我认为它与IEnumerable <>有关.如果我们查看MSDN,IEnumerable本身不是枚举器,但每次调用GetEnumerator()时它都会创建一个枚举器.如果我们查看GetEnumerator,我们会看到foreach(我想象string.Join)调用GetEnumerator(),每次调用它时都会创建一个新状态.举个例子,这里是使用枚举器的代码:
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static IEnumerable<string> Y()
{
var list = new List<string> {"1","2","3","4","5"};
foreach(var i in list)
{
yield return i;
}
}
public static void Main()
{
var ys = Y();
Console.WriteLine("first ys");
Console.WriteLine(string.Join(",", ys));
IEnumerator<string> i = ys.GetEnumerator();
Console.WriteLine(""+i.MoveNext()+": "+i.Current);
Console.WriteLine(""+i.MoveNext()+": "+i.Current);
Console.WriteLine(""+i.MoveNext()+": "+i.Current);
Console.WriteLine(""+i.MoveNext()+": "+i.Current);
Console.WriteLine(""+i.MoveNext()+": "+i.Current);
Console.WriteLine(""+i.MoveNext()+": "+i.Current);
}
}
Run Code Online (Sandbox Code Playgroud)
当MoveNext到达结尾时,它具有预期的python行为.
| 归档时间: |
|
| 查看次数: |
1529 次 |
| 最近记录: |