How do I implement a trait I don't own for a type I don't own?

后端 未结 2 979
忘掉有多难
忘掉有多难 2020-11-22 00:55

I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be ni

2条回答
  •  半阙折子戏
    2020-11-22 01:35

    This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).

    Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.

    Here is an example of how this can be done:

    use std::ops::Shl;
    
    struct BadVec(Vec);
    
    impl Shl for BadVec {
        type Output = BadVec;
    
        fn shl(mut self, elem: T) -> Self::Output {
            self.0.push(elem);
            self
        }
    }
    
    fn main() {
        let mut v = BadVec(vec![1, 2, 3]);
        v = v << 4;
        assert_eq!(vec![1, 2, 3, 4], v.0)
    }
    

    If you implement Deref (DerefMut):

    use std::ops::{Deref, DerefMut};
    
    impl Deref for BadVec {
        type Target = Vec;
    
        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }
    
    impl DerefMut for BadVec {
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.0
        }
    }
    

    you can call Vec methods:

    fn main() {
        let mut v = BadVec(vec![1, 2, 3]);
        v = v << 4;
        v.truncate(2);
        assert_eq!(2, v.len());
    }
    

    Take a look at the newtype_derive crate, it can generate some boilerplate code for you.

提交回复
热议问题