这是否与c有任何等价关系?C中的收益率#
C中的收益率#
回答
否。在Windows上,您可以使用光纤实现类似的效果。
纤维?呵呵,这样的:
产量返回迭代器本机C++使用光纤
http://www.codeproject.com/KB/library/fiber-based_iterator.aspx
虽然C没有在关于枚举一个集合它也有创造协同程序的能力相同的概念产量和纤维。
这里有一些维基百科的文章可能会感兴趣:
http://en.wikipedia.org/wiki/Setcontext http://en.wikipedia.org/wiki/Setjmp/longjmp
不可以。不过,就可以实现与使用setjmp, longjmp用C 类似的效果,但它是非常棘手。
产量由编译器实现为实现状态机的自定义类。虽然不能轻松获得语法(除非您使用之前指定的光纤方法),但您可以非常简单地复制结果,虽然它非常繁琐。下面是(我将在C#中显示,你就必须做在C适当的事情++取决于你所使用的类型):
假设下面的代码:
public IEnumerable<T> GetOddStrings(
IEnumerable<IEnumerable<string>> stringCollections)
{
foreach(var stringCollection in stringCollections)
foreach(var str in stringCollection)
{
if(str.Length %2 != 0) yield return str;
if(str.Length == 42) yield break; // 42 is BAD! Stop immediately
}
}
1)摊开所有的foreach方法为显性枚举来电:
public IEnumerable<T> GetOddStrings(
IEnumerable<IEnumerable<string>> stringCollections)
{
var firstEnumerator = stringCollection.GetEnumerator();
while(firstEnumerator.MoveNext())
{
var secondEnumerator = firstEnumerator.Current.GetEnumerator();
while(secondEnumerator.MoveNext())
{
var str= secondEnumerator.Current;
if(str.Length %2 != 0) yield return str;
if(str.Length == 42) yield break;
}
}
}
2)将所有的局部变量的方法的顶部:
public IEnumerable<T> GetOddStrings(
IEnumerable<IEnumerable<string>> stringCollections)
{
IEnumerator<IEnumerable<string>> firstEnumerator;
IEnumerator<string> secondEnumerator;
string str;
firstEnumerator = stringCollections.GetEnumerator();
while(firstEnumerator.MoveNext())
{
secondEnumerator = firstEnumerator.Current.GetEnumerator();
while(secondEnumerator.MoveNext())
{
str= secondEnumerator.Current;
if(str.Length %2 != 0) yield return str;
if(str.Length == 42) yield break;
}
}
}
3)使用嵌套switch语句移至循环结构。
a)更改状态并继续每个收益回报的循环。 b)如果条件为 c)每个退出条件的收益率突破(下面我们反转if)。
public IEnumerable<T> GetOddStrings(
IEnumerable<IEnumerable<string>> stringCollections)
{
IEnumerator<IEnumerable<string>> firstEnumerator;
IEnumerator<string> secondEnumerator;
string str;
int state = 0;
while(true)
{
switch(state)
{
case 0:
firstEnumerator = stringCollections.GetEnumerator();
// This could be "yield break" but I want to show how you
// could split ifs with significant code in the else
if(!firstEnumerator.MoveNext())
{
state = 1;
continue;
}
secondEnumerator = firstEnumerator.Current;
if(!secondEnumerator.MoveNext) continue;
state = 2;
if(str.Length %2 != 0) yield return str;
continue;
case 1:
yield break;
case 2:
if(str.Length == 42) yield break;
state = 0;
continue;
}
}
}
4)移动到一个类,并从你的方法返回类:一 )产量突破成为“返回false;” b)产量回报变成“this.Current = ??; return true;”
public IEnumerable<T> GetOddStrings(
IEnumerable<IEnumerable<string>> stringCollections)
{
return new OddStringEnumerable(stringCollections);
}
private class OddStringEnumerable : IEnumerable<string>
{
IEnumerable<IEnumerable<string>> stringCollections;
IEnumerator<IEnumerable<string>> firstEnumerator;
IEnumerator<string> secondEnumerator;
string str;
int state;
public OddStringEnumerable(IEnumerable<IEnumerable<string>> stringCollections)
{
this.stringCollections = stringCollections;
}
public string Current { get; private set; }
public bool MoveNext()
{
while(true)
{
switch(state)
{
case 0:
firstEnumerator = this.stringCollections.GetEnumerator();
if(!this.firstEnumerator.MoveNext())
{
this.state = 1;
continue;
}
this.secondEnumerator = this.firstEnumerator.Current;
if(!secondEnumerator.MoveNext) continue;
this.state = 2;
if(str.Length %2 != 0)
{
this.Current = str;
return true;
}
continue;
case 1:
return false;
case 2:
if(str.Length == 42) return false;
this.state = 0;
continue;
}
}
}
}
5)根据需要进行优化。
Coroutines in C使用了一些预处理器hackery,但实现了相当自然的(相对于C中的其他任何东西)yield
。
而你会在Python写:
"""This is actually a built-in function.
def range(start, stop, step):
i = start
while i < stop:
yield i
i = i + step
"""
if __name__ == '__main__':
import sys
start = int(sys.argv[1]) if len(sys.argv) > 2 else 0
stop = int(sys.argv[2]) if len(sys.argv) > 2 else int(sys.argv[1])
step = int(sys.argv[3]) if len(sys.argv) > 3 else 1
for i in range(start, stop, step):
print i,
print
coroutine.h
,您可以用C写:
#include <coroutine.h>
#include <stdio.h>
int range(int start, int stop, int step) {
static int i;
scrBegin;
for (i = start; i < stop; i += step)
scrReturn(i);
scrFinish(start - 1);
}
int main(int argc, char **argv) {
int start, stop, step, i;
start = argc > 2 ? atoi(argv[1]) : 0;
stop = argc > 2 ? atoi(argv[2]) : atoi(argv[1]);
step = argc > 3 ? atoi(argv[3]) : 1;
while ((i = range(start, stop, step)) >= start)
printf("%d ", i);
printf("\n");
}
$ cc range.c $ ./a.out 10 0 1 2 3 4 5 6 7 8 9
对于更复杂的东西,并要求重入的Hamming numbers在Python :
def hamming():
yield 1
i2 = (2*x for x in hamming())
i3 = (3*x for x in hamming())
i5 = (5*x for x in hamming())
m2, m3, m5 = i2.next(), i3.next(), i5.next()
while True:
if m2 < m3:
if m2 < m5:
yield m2
m2 = i2.next()
else:
if m2 > m5: yield m5
m5 = i5.next()
elif m2 == m3: m3 = i3.next()
elif m3 < m5:
yield m3
m3 = i3.next()
else:
if m3 > m5: yield m5
m5 = i5.next()
if __name__ == '__main__':
import sys
it = hamming()
for i in range(str(sys.argv[1]) if len(sys.argv) > 1 else 25):
print it.next(),
print
和C:
#include <coroutine.h>
#include <stdio.h>
int hamming(ccrContParam) {
ccrBeginContext;
ccrContext z[3];
int m2, m3, m5;
ccrEndContext(state);
ccrBegin(state);
state->z[0] = state->z[1] = state->z[2] = 0;
ccrReturn(1);
#define m2_next (2*hamming(&state->z[0]))
#define m3_next (3*hamming(&state->z[1]))
#define m5_next (5*hamming(&state->z[2]))
state->m2 = m2_next, state->m3 = m3_next, state->m5 = m5_next;
while (1) {
if (state->m2 < state->m3) {
if (state->m2 < state->m5) {
ccrReturn(state->m2);
state->m2 = m2_next;
} else {
if (state->m2 > state->m5) ccrReturn(state->m5);
state->m5 = m5_next;
}
} else if (state->m2 == state->m3) state->m3 = m3_next;
else if (state->m3 < state->m5) {
ccrReturn(state->m3);
state->m3 = m3_next;
} else {
if (state->m3 > state->m5) ccrReturn(state->m5);
state->m5 = m5_next;
}
}
ccrFinish(-1);
}
int main(int argc, char **argv) {
int count = argc > 1 ? atoi(argv[1]) : 25, i;
ccrContext z = 0;
for (i = 0; i < count; i++)
printf("%d ", hamming(&z));
printf("\n");
}
$ cc hamming.c $ ./a.out 1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36 40 45 48 50 54
在C#收益简化的集合创建IEnumberables的。
在C++中,你必须使用STL迭代器。
- 1. Python收益率与Ruby收益率
- 2. C#收益率返回
- 3. Tornado的“收益率”与asyncio的“收益率”之间的区别?
- 4. JS发电机:“收益率”与“收益率”有什么不同?
- 5. C#收益率回报预期
- 6. C#收益率是否解锁?
- 7. 红宝石块(收益率)
- 8. 收益率返回无效
- 9. Matlab内部收益率
- 10. 收益率是多少?
- 11. 递归收益率(RoR)
- 12. 事件与收益率
- 13. 收益率连接清单
- 14. Rails:关于收益率
- 15. 收益率回报长度
- 16. Python中的良率与C#中的收益之间的区别
- 17. 错误:流收益率的NodeJS(Windows)中
- 18. 在Java中的收益率返回
- 19. 作为作业有什么收益? myVar的=(收益率)
- 20. AppEngine管线收益率 - 收益率运营商的这种标准用法?
- 21. 计算回报率内部收益率
- 22. Excel中巩固收益率唯一值
- 23. 收益率(X)与(收益率(X)):围绕产量括号在Python
- 24. 收益率传奇打字稿类型错误收益率全部
- 25. 试图了解Unity3D中的c#收益率
- 26. 有人可以解释为什么嵌套的收益率执行(C#收益率回报)吗?
- 27. 这些示例中的收益率和收益之间的差异
- 28. 针对多个块的收益率
- 29. Python的ASYNCIO,期货收益率从
- 30. 蒂收益率不同的字符串
甚至没有关闭! – 2009-06-10 21:48:39
为什么你需要产量?如果你有一个数组,你可以迭代它。收益与IEnumerables相关,您通常会在'foreach'情况下使用它。既然你不能'foreach'你为什么需要创建'yield'? – DevinB 2009-06-12 14:05:42