[][src]Function tao_of_rust::ch11::generator::generaotr

pub fn generaotr()

协程

Basic usage: 生成器示例1

#![feature(generators, generator_trait)]
 
use std::ops::Generator;
 
fn main(){
     
    // let mut gen : Box<Generator<Yield=i32, Return=i32>> = Box::new(||{
    let mut gen  = ||{
        yield 1;
        yield 2;
        yield 3;
        return 4;
    };
    unsafe {
      for _ in 0..4{
         let c = gen.resume();   
         println!("{:?}", c);
      }
    }
}Run

Basic usage: 生成器示例1中的gen生成器实例由编译器自动生成下面等价的代码

#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
 
enum __Gen {
    // (0) 初始状态
    Start,
    // (1) resume方法执行以后
    State1(State1),
    // (2) resume方法执行以后
    State2(State2),
    // (3) resume方法执行以后
    State3(State3),
    // (4) resume方法执行以后,正好完成
    Done
}

struct State1 { x: u64 }
struct State2 { x: u64 }
struct State3 { x: u64 }

impl Generator for __Gen {
    type Yield = u64;
    type Return = u64;

    unsafe fn resume(&mut self) -> GeneratorState<u64, u64> {
        match std::mem::replace(self, __Gen::Done) {
            __Gen::Start => {
                *self = __Gen::State1(State1{x: 1});
                GeneratorState::Yielded(1)
            }
            __Gen::State1(State1{x: 1}) => {
                *self = __Gen::State2(State2{x: 2});
                GeneratorState::Yielded(2)
        }
            __Gen::State2(State2{x: 2}) => {
                *self = __Gen::State3(State3{x: 3});
                GeneratorState::Yielded(3)
            }
            __Gen::State3(State3{x: 3}) => {
                *self = __Gen::Done;
                GeneratorState::Complete(4)
            }
            _ => {
                panic!("generator resumed after completion")
            }
        }
    }
}
 
fn main(){
    let mut gen = {
        __Gen::Start
    };
     
    for _ in 0..4 {
        println!("{:?}", unsafe{ gen.resume()});
    }
}Run

Basic usage: 生成器示例2

#![feature(generators, generator_trait)]
 
use std::ops::Generator;
 
pub fn up_to(limit: u64) -> impl Generator<Yield = u64, Return = u64> {
    move || {
    for x in 0..limit {
         yield x;
    }
    return limit;
    }
}
fn main(){
    let a = 10;
    let mut b = up_to(a);
    unsafe {
      for _ in 0..=10{
         let c = b.resume();   
         println!("{:?}", c);
      }
    }
}Run

Basic usage: 生成器变为迭代器

Generator<Yield=T, Returen=()> yields T and returns ()

#![feature(generators, generator_trait)]
 
use std::ops::{Generator, GeneratorState};
 
pub fn up_to() -> impl Generator<Yield = u64, Return = ()> {
    move || {
        let mut x = 0;
        loop {
            x += 1;
            yield x;
        }
        return ();
    }
}
fn main(){
    let mut gen = up_to();
    unsafe {
      for _ in 0..10{
         match gen.resume() {
             GeneratorState::Yielded(i) => println!("{:?}", i),
            _ => println!("Completed"),
         }
      }
    }
}Run

Basic usage: 生成器变身Futures

yields () and returns Result<T, E> 等价于 Future of T and E

#![feature(generators, generator_trait)]
 
use std::ops::{Generator, GeneratorState};
 
pub fn up_to(limit: u64) -> impl Generator<Yield = (), Return = Result<u64, ()>> {
    move || {
    for x in 0..limit {
         yield ();
    }
    return Ok(limit);
    }
}
fn main(){
    let limit = 2;
    let mut gen = up_to(limit);
    unsafe {
      for i in 0..=limit{
         match gen.resume() {
             GeneratorState::Yielded(v) => println!("resume {:?} : Pending", i),
             GeneratorState::Complete(v) => println!("resume {:?} : Ready", i),
         }
      }
    }
}Run

Basic usage: 跨yield借用会报错

#![feature(generators, generator_trait)]
 
use std::ops::Generator;
 
pub fn up_to(limit: u64) -> impl Generator<Yield = u64, Return = u64> {
    move || {
        let a = 5;
        let ref_a = &a;
    for x in 0..limit {
         yield x;
         if x == 5{
             yield *ref_a;
         }
    }
    return limit;
    }
}
fn main(){
    let a = 10;
    let mut b = up_to(a);
    unsafe {
      for _ in 0..=10{
         let c = b.resume();   
         println!("{:?}", c);
      }
    }
}Run

Basic usage: Pin的用法

#![feature(pin)]
 
use std::pin::{Pin, Unpin};
use std::marker::Pinned;
use std::ptr::NonNull;
 
struct Unmovable {
    data: String,
    slice: NonNull<String>,
    _pin: Pinned,
}
 
impl Unpin for Unmovable {} 
 
impl Unmovable {
    fn new(data: String) -> Pin<Box<Self>> {
        let res = Unmovable {
            data,
            slice: NonNull::dangling(),
            _pin: Pinned,
        };
        let mut boxed = Box::pinned(res);
        let slice = NonNull::from(&boxed.data);
        unsafe {
            let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
            Pin::get_mut_unchecked(mut_ref).slice = slice;
        }
        boxed
    }
}
 
fn main() {
    let unmoved = Unmovable::new("hello".to_string());
    let mut still_unmoved = unmoved;
    assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
 
    let mut new_unmoved = Unmovable::new("world".to_string());
    std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
}Run