So I have the following snippet of code where I want to accept a Vec
of arbitrary values and cast those values into f32. This is to work with floats, ints, unsigned values, etc.
pub struct Vals {
// Our concrete values
mat: Vec<Vec<f32>>,
shape: (usize, usize),
name: String,
}
impl Vals {
pub fn from_vec<T: Into<f32>>(vec: Vec<T>, name: Option<String>) -> Self {
let s1 = vec.iter().len();
let mut as_mat: Vec<Vec<f32>> = Vec::new();
let recasted = vec.iter().map(|&x| x as f32).collect();
as_mat.push(vec);
Vals {
mat: as_mat,
shape: (s1, 1),
name: name.unwrap_or(String::from("")),
}
}
I'm running into an issue on the following line:
let recasted = vec.iter().map(|&x| x as f32).collect();
where it is telling me an
as expression can only be used to convert between primitive types or to coerce to a specific trait object
, but I thought that my specifying the Into
trait would have handled that issue?
I've read through the From and Into Rust Documentation, but nothing there seems to help me address my issue. I see that it mentions how to create itself from another type, hence providing a very simple mechanism for converting between several types
but I would have thought I could handle this. I'm mostly looking for advice on either restructuring my code to make it possible, or directly addressing the bug.
Thank you!
Edit: I've restructured the from_vec
function with the recommendation from @drewtato and now have
pub fn from_vec<T: Into<f32>>(vec: Vec<T>, name: Option<String>) -> Self {
// `Vec` has a `len` method already
let s1 = vec.len();
let recasted = vec.into_iter().map(|x| x.into()).collect();
// Don't need to create the empty `Vec`
let mat = vec![recasted];
Vals {
mat,
shape: (s1, 1),
name: name.unwrap_or_default(),
}
}
but in my test case I've got
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec(){
let v1= vec![1,2,3];
let res = Vals::from_vec(v1, None);
}
}
but it doesn't seem to be working the way I intend. I'm getting
the trait bound `f32: std::convert::From<i32>` is not satisfied
[E0277] the trait `std::convert::From<i32>` is not implemented for
`f32` Help: the following other types implement trait
`std::convert::From<T>`: <f32 as std::convert::From<bool>> <f32 as
std::convert::From<i16>> <f32 as std::convert::From<i8>> <f32 as
std::convert::From<u16>> <f32 as std::convert::From<u8>> Note:
required for `i32` to implement `std::convert::Into<f32>` Note:
required for `f32` to implement `std::convert::TryFrom<i32>`
which I don't understand. I'm reading this as the cast is not implemented, but if I were to implement the cast wouldn't that defeat the purpose of the generic?