Iterator and external state

Hello,

How is it possible to do something like that in Rust ? I just want to control an 'external' iterator (without implementing like a trait) and controlling its state.

I could use 'next' and implement every state like a structure, but I wonder if we can achieve it more easily ?

Because the closure will want to move the state, and it will be no more changeable I fear, while the state is read only inside the iterator...

pub const TAU: f32 = 6.283_185_5;

struct Ugen<T, U> {
    state: T,
    iterator: U,
}
impl<I: Iterator> Ugen<(f32,), Cycle<I>> {
    fn new(freq: f32) -> Self {
    let state =  (freq,);
    let iterator = (0..48000)
    .map(|f| f as f32 * state.0 * (TAU / 48000f32))
    .map(|f| f.sin() * 0.1f32)
    .cycle();

        Self{state, iterator}
}
pub const TAU: f32 = 6.283_185_5;

struct Ugen<U> {
    iterator: U,
}
impl Ugen<()> {
    fn new(freq: f32) -> Ugen<impl Iterator<Item=f32>> {
    let state =  (freq,);
    let iterator = (0..48000)
    .map(|f| f as f32 * state.0 * (TAU / 48000f32))
    .map(|f| f.sin() * 0.1f32)
    .cycle();

        Self{iterator}
}

Thank you, but this give me this error.
Beside, is it possible to keep the state mutable externally ?

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3f8a093975ceee02de9280fe278848f7

error[E0308]: mismatched types
  --> src/lib.rs:14:14
   |
10 |     .map(|f| f as f32 * state.0 * (TAU / 48000f32))
   |          ----------------------------------------- one of the found closures
11 |     .map(|f| f.sin() * 0.1f32)
   |          -------------------- one of the found closures
...
14 |         Self{iterator}
   |              ^^^^^^^^ expected `()`, found struct `std::iter::Cycle`
   |
   = note: expected unit type `()`
                 found struct `std::iter::Cycle<std::iter::Map<std::iter::Map<std::ops::Range<{integer}>, [closure@src/lib.rs:10:10: 10:51 state:_]>, [closure@src/lib.rs:11:10: 11:30]>>`

error[E0277]: `()` is not an iterator
 --> src/lib.rs:7:31
  |
7 |     fn new(freq: f32) -> Ugen<impl Iterator<Item=f32>> {
  |                               ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
  |
  = help: the trait `std::iter::Iterator` is not implemented for `()`
  = note: the return type of a function must have a statically known size

Sorry about that,

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=603223c2c480cb6f0f7460280cfa30d0

There really isn't a point because the closures will capture their own version of the state and oprrate on that. You can't really remove that unless you want to implement Iterator yourself

Ok thank you for that.

I don't understand still the subtle difference : it seems you just replaced 'Self' with Ugen between the two versions.
So it means "Self" refers not to the "naked type" but the type + the trait bounds, while the type name Ugen just refers to the naked type ?

Yes, Self is always exactly the type defined at the top of the impl, whereas Ugen is the generic type with it's parameters inferred.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.