[−][src]Attribute Macro propane::generator
#[generator]
This macro can be applied to functions to make them into generators.
Functions annotated with this attribute use the yield
keyword, instead of the return
keyword. They yield an item and then continue. When you call a generator function, you get an
iterator of the type it yields, rather than just one value of that type.
You can still use the return
keyword to terminate the generator early, but the return
keyword cannot take a value; it only terminates the function.
The behavior of ?
is also modified in these functions. In the event of an error, the
generator yields the error value, and then the next time it is resumed it returns None
.
Forbidding self-references
Unlike async functions, generators cannot contain self-references: a reference into their stack space that exists across a yield point. Instead, anything you wish to have by reference you should move out of the state of the generator, taking it as an argument, or else not holding it by reference across a point that you yield.
Unstable features
In order to use this attribute, you must turn on all of these features:
generators
generator_trait
try_trait
Example
#![feature(generators, generator_trait, try_trait)] #[propane::generator] fn fizz_buzz() -> String { for x in 1..101 { match (x % 3 == 0, x % 5 == 0) { (true, true) => yield String::from("FizzBuzz"), (true, false) => yield String::from("Fizz"), (false, true) => yield String::from("Buzz"), (..) => yield x.to_string(), } } } fn main() { let mut fizz_buzz = fizz_buzz(); assert_eq!(&fizz_buzz.next().unwrap()[..], "1"); assert_eq!(&fizz_buzz.next().unwrap()[..], "2"); assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz"); assert_eq!(&fizz_buzz.next().unwrap()[..], "4"); assert_eq!(&fizz_buzz.next().unwrap()[..], "Buzz"); assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz"); assert_eq!(&fizz_buzz.next().unwrap()[..], "7"); // yada yada yada let mut fizz_buzz = fizz_buzz.skip(90); assert_eq!(&fizz_buzz.next().unwrap()[..], "98"); assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz"); assert_eq!(&fizz_buzz.next().unwrap()[..], "Buzz"); assert!(fizz_buzz.next().is_none()); }