ES6 Generator與C#迭代器
阿新 • • 發佈:2020-07-27
ES6 Generator:
利用阮大神的書中描述的:
形式上,Generator 函式是一個普通函式,但是有兩個特徵。一是,function關鍵字與函式名之間有一個星號;二是,函式體內部使用yield表示式,定義不同的內部狀態(yield在英語裡的意思就是“產出”)。
其實簡單來說就是通過各種狀態,函式可以返回多個值,看完文章,我覺著以下這功能可能會用的比較多
function* objectEntries(obj) { let propKeys = Reflect.ownKeys(obj); for (let propKey of propKeys) { yield [propKey, obj[propKey]]; } } let jane= { first: 'Jane', last: 'Doe' }; for (let [key, value] of objectEntries(jane)) { console.log(`${key}: ${value}`); } // first: Jane // last: Doe
上面程式碼中,物件jane
原生不具備 Iterator 介面,無法用for...of
遍歷。這時,我們通過 Generator 函式objectEntries
為它加上遍歷器介面,就可以用for...of
遍歷了。加上遍歷器介面的另一種寫法是,將 Generator 函式加到物件的Symbol.iterator
屬性上面。
function* objectEntries() { let propKeys = Object.keys(this); for (let propKey of propKeys) { yield [propKey, this[propKey]]; } } let jane = { first: 'Jane', last: 'Doe' }; jane[Symbol.iterator] = objectEntries; for (let [key, value] of jane) { console.log(`${key}: ${value}`); } // first: Jane// last: Doe
優雅的Generator非同步應用模組:thunkify和co模組;
C# yield
跟ES6中的Generator有異曲同工之妙.可以參考微軟官方文件.
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/yield
主要看例子吧,例子很明顯也是可以使用迭代器的方式每次返回一個值,但最終可以返回多個值。
迭代器方法:
public class PowersOf2 { static void Main() { // Display powers of 2 up to the exponent of 8: foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); } } public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } } // Output: 2 4 8 16 32 64 128 256 }
迭代器的get訪問器
public static class GalaxyClass { public static void ShowGalaxies() { var theGalaxies = new Galaxies(); foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy) { Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString()); } } public class Galaxies { public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy { get { yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 }; yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }; yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 }; yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 }; } } } public class Galaxy { public String Name { get; set; } public int MegaLightYears { get; set; } } }