这个有效:
let hello = "Hello ".to_string();
let world = "world!";
let hello_world = hello + world;
但这不是:
let hello = "Hello ".to_string();
let world = "world!".to_string();
let hello_world = hello + world;
但是这样做:
let hello = "Hello ".to_string();
let world = "world!".to_string();
let hello_world = hello + &world;
那是因为 String
需要一个指向第二个 String
的原始字符串切片的指针吗?如果是,为什么?
最佳答案
答案分为两部分。
第一部分是+
涉及使用 an Add
trait implementation .它仅适用于:
impl<'a> Add<&'a str> for String
因此,字符串连接仅在以下情况下有效:
- 左侧是
String
- 右侧可强制转换为
&str
注意:与许多其他语言不同,加法会消耗 Left Hand Side 参数。
因此,第二部分是当 &str
时可以使用什么样的参数?是预期的吗?
显然,一个 &str
可以按原样使用:
let hello = "Hello ".to_string();
let hello_world = hello + "world!";
否则,对实现 Deref<&str>
的类型的引用会起作用,结果是 String
这样做 &String
作品:
let hello = "Hello ".to_string();
let world = "world!".to_string();
let hello_world = hello + &world;
还有其他实现呢?他们都有问题。
-
impl<'a> Add<String> for &'a str
需要前置,效率不如追加 -
impl Add<String> for String
当一个参数足够时,不必要地消耗两个参数 -
impl<'a, 'b> Add<&'a str> for &'b str
隐藏无条件内存分配
最后,Rust 尽可能明确的哲学解释了不对称选择。
或者更明确地说,我们可以通过检查操作的算法复杂性来解释选择。假设左侧尺寸为M,右侧尺寸为N,则:
-
impl<'a> Add<&'a str> for String
是 O(N)(摊销) -
impl<'a> Add<String> for &'a str
是 O(M+N) -
impl<'a, 'b> Add<&'a str> for &'b str
是 O(M+N) -
impl Add<String> for String
是 O(N)(摊销)...但需要分配/克隆右侧的任何内容。
关于rust - 为什么不引用其中一个字符串就无法在 Rust 中连接两个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39917173/