prices isn’t consumed with iter(), but it does give an iterator that yields references. However, you can call prices.iter().cloned() to get an iterator that yields values.
It’s a fine approach for cheap Clone types. If you wanted references, you can do:
fn ema<'a, I>(mut i: I, period: usize) -> impl Iterator<Item = &'a f32>
where
I: Iterator<Item = &'a f32>,
You don’t need the cloned() call for this variant but now you’re yielding refs as well. There’re ways to abstract this as well but I’d just stick to cloned() here.
I tried to follow this, but I get an (expected) lifetime error
fn ema<'a, I: 'a>(mut i: I, period: usize) -> impl Iterator<Item = &'a f32> + Clone + 'a
where
I: Iterator<Item = &'a f32> + Clone,
{
let alpha = (2 / (period + 1)) as f32;
let ema0 = i.by_ref().take(1).next().unwrap();
i.scan(ema0, move |ema_prev, price| {
*ema_prev = &(*ema_prev + alpha * (price - *ema_prev));
Some(*ema_prev)
})
}
error[E0597]: borrowed value does not live long enough
--> src\technical_analysis.rs:102:22
|
102 | *ema_prev = &(*ema_prev + alpha * (price - *ema_prev));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value only lives until here
| |
| temporary value does not live long enough
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 95:8...
I think I'm missing something? To add, the value approach does work, but will become expensive once I have larger objects
This seems to be saying that I can be prices asf32 or as &f32, and we abstract over either. Fair enough. What I return is a f32 that could be borrowed if chained to another function, though in this instance, returns an iterator yielding values in this case.