Updated Answer
This is not possible. A String has to be a single contiguous allocation in memory. If you want to roll your own simple solution you can probably define a type like this:
struct MyString {
parts: Vec<String>,
}
impl MyString {
fn concat(&mut self, other: String) {
self.parts.push(other);
}
}
However re-implementing every useful String method for this custom type is going to be tedious and error-prone. You can find a Rust crate which implements a Rope data structure, and an-rope seems to be such a crate, but only a tiny fraction of String methods are supported.
I gave this answer when I interpreted OP's question as one about invalidating and moving variables:
Original Answer
You can invalidate any non-Copy variable by moving it somewhere else, like by passing it to the drop function:
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // s1 invalidated
drop(s2); // s2 invalidated
// now only s3 is usable
}
If this is a common pattern in your application you can just write a function which takes ownership of 2 Strings and returns the concatenated result:
fn concat(s1: String, s2: String) -> String {
s1 + &s2
}
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = concat(s1, s2); // s1 & s2 invalidated
// now only s3 is usable
}
s1ands2are different allocations. So the best you can do in the standard library is appends2at the end ofs1's buffer.