I'm trying to implement the initialization of a struct with generic fields, where one field is initialized with a user-defined value and the other always defaults to a 1 depending on the generic type of the rest of the fields, just as it works with Default::default() for the value 0:
struct Vector<T>{
x: T,
w: T,
}
struct Point<T>{
x: T,
w: T,
}
impl<T> Vector<T> {
fn new(x: T) -> Self where T: Default {
Self {x, w: Default::default() } // <= returns 0i64, 0f64, etc.
}
}
impl<T> Point<T>{
fn new(x: T) -> Self where T: Default {
Self {x, w: /* how to return a 1i64, 1f64, etc. ?*/ }
}
}
So that when called:
let vector_i = Vector::new(2i64);
let vector_f = Vector::new(3.5f64)
let point_i = Point::new(2i64);
let point_f = Point::new(3.5f64);
Initialize as follows:
// works correctly thanks to Default::default() returning 0 or 0.0 automatically...
vector_i Vector { x: 2, w: 0}
vector_f Vector {x: 3.5, w: 0.0}
// how to make it work?
point_i: Point { x: 2, w: 1 }
point_f: Point { x: 3.5 w: 1.0 }
Is there a way to make it work without separate implementation blocks like impl Point<f64> or impl Point<64> so that it is implemented in a single generic impl block just like with Vector?
To elaborate a bit, your original code isn’t restricted to numeric types. So, you need to either come up with an implementation that works for arbitrary types (T = HashMap<String,u32>>, for example) or somehow disallows them via a trait bound.
Note that One is a supertrait of Num, so if you use Num anyway, you don't have to explicitly ask for One - it will be required (and available) automatically.