如何在不复制的情况下将两个字符串连接成第三个字符串?
How to concatenate two strings into the third string without copying?
我是 Rust 新手,目前正在阅读 Rust 编程语言一书。
我对这个例子很好奇:
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
}
是否有可能不仅取得 s1
的所有权,而且取得 s2
的所有权,所以 s2
和 s1
一样无效,使得 s3
唯一可用的变量?
更新答案
这是不可能的。 String
必须是内存中的单个连续分配。如果您想推出自己的简单解决方案,您可以定义这样的类型:
struct MyString {
parts: Vec<String>,
}
impl MyString {
fn concat(&mut self, other: String) {
self.parts.push(other);
}
}
然而,为这个自定义类型重新实现每个有用的 String
方法将是乏味且容易出错的。您可以找到一个实现 Rope data structure, and an-rope 的 Rust crate 似乎是这样一个 crate,但只支持一小部分 String
方法。
当我将 OP 的问题解释为关于无效和移动变量的问题时,我给出了这个答案:
原答案
您可以通过将任何非 Copy
变量移动到其他地方来使其无效,例如将其传递给 drop
函数:
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
}
如果这是您应用程序中的常见模式,您只需编写一个函数,它拥有 2 String
s 和 returns 串联结果的所有权:
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
}
我是 Rust 新手,目前正在阅读 Rust 编程语言一书。
我对这个例子很好奇:
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
}
是否有可能不仅取得 s1
的所有权,而且取得 s2
的所有权,所以 s2
和 s1
一样无效,使得 s3
唯一可用的变量?
更新答案
这是不可能的。 String
必须是内存中的单个连续分配。如果您想推出自己的简单解决方案,您可以定义这样的类型:
struct MyString {
parts: Vec<String>,
}
impl MyString {
fn concat(&mut self, other: String) {
self.parts.push(other);
}
}
然而,为这个自定义类型重新实现每个有用的 String
方法将是乏味且容易出错的。您可以找到一个实现 Rope data structure, and an-rope 的 Rust crate 似乎是这样一个 crate,但只支持一小部分 String
方法。
当我将 OP 的问题解释为关于无效和移动变量的问题时,我给出了这个答案:
原答案
您可以通过将任何非 Copy
变量移动到其他地方来使其无效,例如将其传递给 drop
函数:
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
}
如果这是您应用程序中的常见模式,您只需编写一个函数,它拥有 2 String
s 和 returns 串联结果的所有权:
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
}