yield
Summary
Pauses and exits a function and, optionally, evaluates an expression that can be accessed via the ISequence
Syntax
yield [expression];
Parameters
- expression
- Optional. The expression to evaluate and return. If no expression is provided, undefined will be returned.
Description
The yield statement will pause and exit the current function, and, if an expression is provided to the yield statement, the expression will be evaluated (within the context of the current function) and the evaluated value can be accessed via the ISequence<T>.value
method.
The yield statement can only be used for functions and methods returning ISequence<T>
, known as "generator functions." Generator functions are basically "constructors" that construct a sequence object. Sequence objects can be "iterated" on demand; after encountering a yield
statement, each call to the ISequence<T>.next()
method will continue execution of the function from its last yield
. Thus, unlike return
, the yield
statement will not exit the function but, instead, pauses the function's execution and resumes execution when the ISequence<T>.next()
method is called.
The type of the expression provided to the yield
statement must match the type argument specified for T
in the ISequence<T>
return type; otherwise, a compiler error will be raised. For example, if the generator function's return type is ISequence<int>
, the yield statement must return a value of type int
.
Statements appearing after a yield
statement will not be evaluated until the function resumes.
'foreach' over Dictionary<T> in generators
In a generator function that returns a sequence object of type ISequence<T>
, foreach
loops that iterate System.Dictionary<T>
require O(n) memory since the dictionary keys will be copied.
Examples
1 2 3 4 5 6 7 8 9 10 11 12 13 | import System; ISequence< int > counter() { yield 0; yield 1; yield 2; } auto sequence = counter(); while (sequence.next()) { int x = sequence.value(); Console.trace(x); } |
1 2 3 4 5 6 7 8 9 10 11 | import System; ISequence< int > range( int start, int stop) { for ( int i = start; i < stop; ++i) { yield i; } } foreach ( int x in range(0, 10)) { Console.trace(x); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import System; external require; external fs = require( "fs" ); ISequence< string > fileReader() { fs.readFile( "1.txt" , void (err1, data1) { yield data1.toString(); fs.readFile( "2.txt" , void (err2, data2) { yield data2.toString(); }); }); } auto reader = fileReader(); unsigned int fileNumber = 0; while (reader.next()) { Console.trace( "File #" + fileNumber.toString()); Console.trace(reader.value()); } |
See Also
Share
HTML | BBCode | Direct Link