這是否與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. JS發電機:「收益率」與「收益率」有什麼不同?
- 4. C#收益率是否解鎖?
- 5. C#收益率回報預期
- 6. 遞歸收益率(RoR)
- 7. 收益率回報長度
- 8. 事件與收益率
- 9. Python中的良率與C#中的收益之間的區別
- 10. 在Java中的收益率返回
- 11. 錯誤:流收益率的NodeJS(Windows)中
- 12. 作爲作業有什麼收益? myVar的=(收益率)
- 13. 計算回報率內部收益率
- 14. Excel中鞏固收益率唯一值
- 15. 收益率傳奇打字稿類型錯誤收益率全部
- 16. 試圖瞭解Unity3D中的c#收益率
- 17. im2double收益率不同的結果
- 18. 蒂收益率不同的字符串
- 19. Notes會話收益率的票據URL
- 20. 不同進程之間的收益率
- 21. 針對多個塊的收益率
- 22. 如何在UML序列圖中描述C#收益率回報?
- 23. 將收益率轉換成VB.NET
- 24. 與lodash收益率意外輸出
- 25. 紅寶石概念 - 收益率
- 26. 替代方式編寫收益率
- 27. WCF序列化收益率 - 菜鳥
- 28. 個月上月基金收益率(%)
- 29. Scrapy/Python:以收益率處理值
- 30. 如何與異常收益率產生
甚至沒有關閉! – 2009-06-10 21:48:39
爲什麼你需要產量?如果你有一個數組,你可以迭代它。收益與IEnumerables相關,您通常會在'foreach'情況下使用它。既然你不能'foreach'你爲什麼需要創建'yield'? – DevinB 2009-06-12 14:05:42