Currently Add is implemented on Vec only to append slices:
impl<'a, T: Clone> Add<&'a [T]> for Vec<T> {
type Result = Vec<T>;
fn add(self, rhs: &'a [T]) -> Vec<T> { ... }
}
This is really convenient when Vec is used in folds as an accumulator. While sometimes map()+collect::<Vec<_>>() can be used instead of fold(), it is not always the case, for example, when there is something else in the accumulator. The same thing also holds for String.
However, this does require that the RHS must be a slice, which is not always possible. While you can write e.g.
let v = vec![1u, 2, 3];
v.iter().fold(Vec::new(), |a, &x| a + [x].as_slice())
it is really ugly. For strings, however, even this is not possible - you can’t turn a char into a slice in general without allocation. You have to drop to push() method which does not return the string back, so the closure must have two statements in it:
let s = "abcde".to_string();
s.chars().fold(String::new(), |mut a, c| { a.push(c); a });
If Vec<T> and String implemented Add<T>/Add<char>:
impl<T> Add<T> for Vec<T> {
type Result = Vec<T>;
fn add(self, rhs: T) -> Vec<T> {
self.push(rhs);
self
}
}
(similarly for String), then the fold can be written just as
let s = "abcde".to_string();
s.chars().fold(String::new(), |a, c| a + c);
Other growable collections could probably be improved in a similar way.
What do you think?

for