为什么不能在 Rust 中连接两个字符串而不引用其中之一? [英] Why is it not possible to concatenate two Strings in Rust without taking a reference to one of them?

查看:53
本文介绍了为什么不能在 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 的原始字符串切片的指针?如果是,为什么?

Is that because the String needs a pointer to the original string slice of the second String? If so, why?

推荐答案

答案分为两部分.

第一部分是 + 涉及使用 一个 添加 trait 实现.它仅用于:

The first part is that + involves using an Add trait implementation. It is implemented only for:

impl<'a> Add<&'a str> for String

因此,字符串连接仅适用于:

Therefore, string concatenation only works when:

  • 左边是一个String
  • 右侧可强制转换为 &str

注意:与许多其他语言不同,加法会消耗左侧参数.

因此,第二部分是当需要 &str 时可以使用什么样的参数?

The second part, therefore, is what kind of arguments can be used when a &str is expected?

显然,&str 可以按原样使用:

Obviously, a &str can be used as is:

let hello = "Hello ".to_string();
let hello_world = hello + "world!";

否则,对实现 Deref<&str> 的类型的引用将起作用,结果证明 String 会起作用 &String作品:

Otherwise, a reference to a type implementing Deref<&str> will work, and it turns out that String does so &String works:

let hello = "Hello ".to_string();
let world = "world!".to_string();

let hello_world = hello + &world;

<小时>

其他实现呢?他们都有问题.


And what of other implementations? They all have issues.

  • impl<'a>添加<字符串>for &'a str 需要前置,不如 append 高效
  • impl Addfor String 当一个参数足够时不必要地消耗两个参数
  • impl<'a, 'b>添加<&'a str>for &'b str 隐藏了无条件的内存分配
  • impl<'a> Add<String> for &'a str requires prepending, which is not as efficient as appending
  • impl Add<String> for String needlessly consume two arguments when one is sufficient
  • impl<'a, 'b> Add<&'a str> for &'b str hides an unconditional memory allocation

最后,不对称的选择是由 Rust 尽可能明确的哲学解释的.

In the end, the asymmetric choice is explained by Rust philosophy of being explicit as much as possible.

或者更明确地说,我们可以通过检查操作的算法复杂性来解释选择.假设左侧的尺寸为 M,右侧的尺寸为 N,则:

Or to be more explicit, we can explain the choice by checking the algorithmic complexity of the operation. Assuming that the left-hand side has size M and the right-hand side has size N, then:

  • impl<'a>添加<&'a str>对于字符串 是 O(N)(摊销)
  • impl<'a>添加<字符串>对于 &'a str 是 O(M+N)
  • impl<'a, 'b>添加<&'a str>对于 &'b str 是 O(M+N)
  • impl Addfor String 是 O(N)(摊销)...但需要分配/克隆右侧无用.
  • impl<'a> Add<&'a str> for String is O(N) (amortized)
  • impl<'a> Add<String> for &'a str is O(M+N)
  • impl<'a, 'b> Add<&'a str> for &'b str is O(M+N)
  • impl Add<String> for String is O(N) (amortized)... but requires allocating/cloning the right-hand side for nothing.

这篇关于为什么不能在 Rust 中连接两个字符串而不引用其中之一?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆