My intention is to customize behaviour of value function in the following code:
struct GenVal<T> {
gen_val: T,
}
impl<T> GenVal<T> {
fn value(&self) -> &T {
&self.gen_val
}
}
impl GenVal<u32> {
fn value(&self) -> &u32 {
&self.gen_val
}
}
fn main() {
let y = GenVal { gen_val: 3i32 };
println!("{}", y.value());
}
It tells that ‘value’ is defined twice – seems completely ridiculous to me.
Could anyone please explain why is this happening?
Godbolt example: https://godbolt.org/z/czE3Pqfbx
4
As Alexander said, you can’t.
However, you can do something similar: Creating a different trait that uses GenVal
. There you can give a default implementation as well as specific ones. However, you have to give an empty implementation for any type you want to use, thus it is not exactly your intended behaviour:
struct GenVal<T:Sized> {
gen_val: T,
}
trait FromGenVal {
fn from_gen_val(&mut self, g: &GenVal<Self>) where Self: Sized+Clone {
*self = g.gen_val.clone()
}
}
impl FromGenVal for i32 {
fn from_gen_val(&mut self, g: &GenVal<Self>) {
*self = g.gen_val.clone()*2 } // specific behaviour
}
impl FromGenVal for i16 {} // empty implementation for default behaviour
fn main() {
let x1 = GenVal { gen_val: 3i32 };
let x2 = GenVal { gen_val: 3i16 };
let mut z1: i32 = 0;
let mut z2: i16 = 0;
z1.from_gen_val(&x1);
z2.from_gen_val(&x2);
println!("{}, {}", z1, z2);
}
Alexander Krauze’s comment looks like a great answer.
You cannot do this kind of specialization in Rust today (and probably not any day soon). You can have new methods defined for different concrete types, but they cannot overlap. There are some tricks with macros you could use, but they are limited in what they can do.