I want to define methods for Untyped
and Unit
or basically every type, but I want to specialize a few methods just for Unit
.
The pr
You are trying to specialize a method defined in an inherent impl
, rather than specializing a method defined in a trait. This appears to not be supported at the moment, even after adding default
to the "non special" length
method. RFC 1210 mentions inherent impl
s as a possible extension, which I understand as not being considered for implementation at the moment.
As a workaround, consider moving your method to a trait. This requires specialization to be enabled to work, so you'll need to use a nightly compiler until the feature is stabilized.
Instead of defining the default implementation on the trait, we define it in the general impl
. We need to add the default
contextual keyword to that function.
#![feature(specialization)]
trait VectorExt<T>
where
T: Float,
{
fn length(&self) -> T;
}
impl<T, Type> VectorExt<T> for Vector<T, Type>
where
T: Float,
{
default fn length(&self) -> T {
println!("NON SPECIAL");
T::one()
}
}
impl<T> VectorExt<T> for Vector<T, Unit>
where
T: Float,
{
fn length(&self) -> T {
println!("SPECIAL");
T::one()
}
}
// This `impl` is not strictly necessary,
// but it will let users of your type
// use the `length` method
// without having to `use` the `VectorExt` trait.
impl<T, Type> Vector<T, Type>
where
T: Float,
{
fn length(&self) -> T
where
Self: VectorExt<T>,
{
VectorExt::<T>::length(self)
// can also be written as: <Self as VectorExt<T>>::length(self)
}
}
playground