我读了大约String秒的书,发现他们用&*组合在一起来转换一段文字.下面是它所说的:

use std::net::TcpStream;

TcpStream::connect("192.168.0.1:3000"); // Parameter is of type &str.

let addr_string = "192.168.0.1:3000".to_string();
TcpStream::connect(&*addr_string); // Convert `addr_string` to &str.

换句话说,他们说他们正在把String分转换成&str分.但为什么要使用上述两种符号进行转换呢?这不应该用其他方法吗?&不是意味着我们在引用它,然后用*go 引用它吗?

推荐答案

In short:*触发一个显式的deref,可以通过ops::Deref重载.


更多细节

看看下面的代码:

let s = "hi".to_string();  // : String
let a = &s;

a是什么类型的?简直是&String!这并不奇怪,因为我们参考了String.好吧,但是这个呢?

let s = "hi".to_string();  // : String
let b = &*s;   // equivalent to `&(*s)`

b是什么类型的?是&str!哇,发生什么事了?

注意,首先执行*s.与大多数操作符一样,解引用操作符*也是可重载的,并且可以将操作符的使用视为*std::ops::Deref::deref(&s)的语法糖(注意,我们在这里递归地解引用!).String does过载此操作员:

impl Deref for String {
    type Target = str;
    fn deref(&self) -> &str { ... }
}

因此,*s实际上是*std::ops::Deref::deref(&s),其中deref()函数具有返回类型&str,然后再次取消引用.因此,*s具有str型(注意缺少&).

因为str本身没有大小,也不是很方便,所以我们想用&str来代替它.我们可以通过在表达式前面添加&来实现这一点!塔达,现在我们到了&str型!


&*s更像是手动和明确的形式.通常,Deref重载是通过自动解除强制来使用的.当目标类型固定后,编译器将为您解除:

fn takes_string_slice(_: &str) {}

let s = "hi".to_string();  // : String
takes_string_slice(&s); // this works!

Rust相关问答推荐

如何访问Rust存储值的内存地址

在函数内定义impl和在函数外定义impl的区别

如何获取Serde struct 的默认实例

新创建的变量的绑定生存期

重写Rust中的方法以使用`&;mut self`而不是`mut self`

在Rust中,Box:ed struct 与普通 struct 在删除顺序上有区别吗?

应为关联类型,找到类型参数

找不到 .has_func 或 .get_func 的 def

确保参数是编译时定义的字符串文字

Windows 上 ndarray-linalg 与 mkl-stats 的链接时间错误

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

sha256 摘要仅适用于 &*

我可以在 Rust 中 serde struct camel_case 和 deserde PascalCase

decltype、dyn、impl traits,重构时如何声明函数的返回类型

为什么要这样编译?

如果不满足条件,如何在 Rust 中引发错误

&str 的编译时拆分是否可能?

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

无法把握借来的价值不够长寿,请解释

如何从 Rust 中不同类型的多个部分加入 Path?