How can I specialize a method for a specific generic type?

前端 未结 1 1594
悲哀的现实
悲哀的现实 2021-01-22 14:03

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

相关标签:
1条回答
  • 2021-01-22 14:12

    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 impls 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

    0 讨论(0)
提交回复
热议问题