How do I perform operations on different numeric types while computing the average in an idiomatic Rust manner? -
i tried implement small module calculate mean of vector:
pub mod vector_calculations { pub fn mean(vec: &vec<i32>) -> f32 { let mut sum: f32 = 0.0; el in vec.iter() { sum = el + sum; } sum / vec.len() } }
as far can tell compiler error, there 2 problems code:
error[e0277]: trait bound `&i32: std::ops::add<f32>` not satisfied --> src/main.rs:6:22 | 6 | sum = el + sum; | ^ no implementation `&i32 + f32` | = help: trait `std::ops::add<f32>` not implemented `&i32` error[e0277]: trait bound `f32: std::ops::div<usize>` not satisfied --> src/main.rs:9:13 | 9 | sum / vec.len() | ^ no implementation `f32 / usize` | = help: trait `std::ops::div<usize>` not implemented `f32`
i'm trying add &i32
f32
, i'm trying divide f32
usize
.
i solve second error changing last line to:
sum / (vec.len() f32)
is how rust programmer this?
furthermore, don't know how solve first error. has done , why?
yes, dereferencing values , converting numeric types normal in rust. these conversions programmer recognize edge cases possible. loganfsmyth points out:
an
i32
can hold values greaterf32
can represent accurately
unfortunately, compiler can't tell what's "correct" case, still have on guard.
for it's worth, i'd write current implementation using iterator::sum
:
fn mean(items: &[i32]) -> f64 { let sum: f64 = items.iter().map(|&v| v f64).sum(); sum / (items.len() f64) }
you should handle case input empty avoid dividing zero:
fn mean(items: &[i32]) -> option<f64> { let len = items.len(); if len == 0 { none } else { let sum: f64 = items.iter().map(|&v| v f64).sum(); some(sum / (len f64)) } }
using method what solution calculating average sum of values exceeds double's limits?, made bit more iterator-heavy:
fn mean2(ary: &[i32]) -> f64 { ary.iter().enumerate().fold(0.0, |avg, (i, &x)| { avg + ((x f64 - avg) / (i + 1) f64) }) }
see also:
Comments
Post a Comment