Reputation: 33
I'm new to Rust and I'm currently reading The Rust Programming Language book.
I'm curious about this example:
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
}
Is it possible to take ownership not only of s1
, but also of s2
, so s2
gets invalidated as well as s1
, making s3
the only possible variable that remains usable?
Upvotes: 3
Views: 4053
Reputation: 15155
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 String
s 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
}
Upvotes: 5