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
This would make things like
vec << 4
possible, which would be nice sugar forvec.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<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
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<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
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.
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}