Closed as not planned
Description
Proposal
Problem statement
Getting a reference to the value you just pushed to a vector requires an extra call and unwrap:
let mut v = Vec::new();
v.push(42);
*v.last_mut().unwrap() = 43;
Motivating examples or use cases
I'm currently porting https://github.com/Naruyoko/OmegaNum.js/ to Rust, and this is a common pattern all over:
x.array[i+1]=(x.array[i+1]||0)+1;
This is directly translated as
if x.is_empty() {
x.push(0);
}
let last_mut = x.last_mut().unwrap();
*last_mut += 1;
With this, this could be the following:
let last_mut = x.last_mut().unwrap_or(x.push(0));
*last_mut += 1;
which is much nicer.
Solution sketch
Change Vec::push
to return a reference to the pushed value:
pub fn push(&mut self, value: T) -> &mut T {
let len = self.len;
if len == self.buf.capacity() {
self.buf.grow_one();
}
unsafe {
let end = self.as_mut_ptr().add(len);
ptr::write(end, value);
self.len = len + 1;
&mut *end
}
}
Alternatives
Alternatively, Vec::last_or_push(default: T) -> &T
, along with 3 other variations for mutability and laziness, could make the above translate in only one line - maybe it would be better, but both would be nice. See issue #465.