The Default implementation for Vec<T> calls Vec::new, which is basically free (doesn't allocate any memory), so at least if your field is a Vec I wouldn't worry about this. Default implementations for other types are often comparably cheap.
Also note your change could be a method on Foo taking &mut self—it doesn't need to take ownership of its argument.
You're asking for something like this. The general problem is that if you take out of the reference, then panic while constructing a replacement, you need a default object in place in order to avoid a double-free during the stack unwinding. So you must either create a default value, or decide that you will abort on panic rather than unwind.
Yet another solution is to wrap the type inside an Option and use Option::take to steal the Some-valued field, leaving a None in its place. This is basically a one-stop shop for the "default object" pattern, even for non-Default types.
Unfortunately you cant move arr. I updated the example so it's more clear now.
It basically says:
error[E0507]: cannot move out of `self.arr` which is behind a mutable reference
--> src/runtime/worker/worker.rs:70:20
|
70 | self.arr = self.arr.into_iter().collect();
| ^^^^^^^^ move occurs because `self.arr` has type `Vec<u8>`, which does not implement the `Copy` trait
Apparently it's possible by using a third party module, but it comes with a cost, check @skysch's answer. As I am new to Rust I would rather just use standard features.
As pointed out by @cole-miller creating an empty vector with new is rather inexpensive, so I will go with this.
Another option would be to use Option (as pointed out by @H2CO3), but it would mean checking every time for None.