为什么在 Rust 中解引用字符串(而不是 &String)有效?

问题描述 投票:0回答:1

在下面的代码中,在calculate_length函数中我们发送的是String而不是&String,但解引用是有效的。我预计会出现错误: 类型

String
无法取消引用

但是代码编译并运行时没有任何错误/警告。

fn main() {
    let  x = String::from("hello world");
    let z = calculate_length(x);

    println!("{:}", z);
}

fn calculate_length(s: String) -> usize {
    (*s).len()
}

Playgorund 代码在这里

rust reference rust-cargo dereference
1个回答
0
投票

首先,

String
实现了
Deref
,这意味着您可以在其上使用解引用运算符
*
。但是,您部分正确地认为
s
无法取消引用。如果您编写
let x = *s;
,它将无法编译,因为这会复制
String
的目标类型
str
。并且
str
无法复制,因为它由于未调整大小而未实现
Copy

但是,虽然

*s
不能是,但它是一个有效的位置表达式,这意味着您可以对其执行一些操作,例如分配给它,使其成为引用
&*s
,或者调用它的方法。

方法非常灵活,可以添加引用和取消引用,以便找到具有指定名称的合适函数。在

(*s).len()
中,该方法添加
&
以便调用
str::len
,这看起来像
str::len(&*s)
展开了。添加的引用使
str
无需被复制。然后取消引用
*s
扩展为
str::len(&*Deref::deref(&s))

© www.soinside.com 2019 - 2024. All rights reserved.