rust - 为什么不引用其中一个字符串就无法在 Rust 中连接两个字符串?

标签 rust

这个有效:

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/

相关文章:

rust - 如何修复 : expected concrete lifetime, 但找到绑定(bind)的生命周期参数

rust - 如何管理 Vec 中 CString 的生命周期?

recursion - Rust 中的递归生成器

rust - Rust 中 ".map(|&x| x)"的目的是什么

mongodb - 使用 mongodb 驱动程序编译时 Rust 链接错误

rust - 添加到基于 RefCell 构建的二叉树时,借用的值不会存在足够长的时间

rust - 如何在 Diesel 中针对 Postgres 数据库执行带有子查询的删除?

types - 了解类型归属问题

rust - 动态推断字符串的类型

rust - 如何为构建器提供可变引用,但仅提供对构建对象的不可变引用?