这有效:
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特质实现 https://doc.rust-lang.org/std/ops/trait.Add.html。它仅针对以下目的实施:
impl<'a> Add<&'a str> for String
因此,字符串连接仅在以下情况下有效:
注意:与许多其他语言不同,加法将消耗左侧参数。
因此,第二部分是当&str
是期待?
显然,一个&str
可以按原样使用:
let hello = "Hello ".to_string();
let hello_world = hello + "world!";
否则,对实现的类型的引用Deref<&str>
会起作用,事实证明String
这样做&String
works:
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) (摊销)...但需要免费分配/克隆右侧。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)