`*` 运算符和 `deref()` 方法有什么区别? [重复]

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

我被告知的是,一旦一个对象(在此转换中

sth
)实现了
Drop
特征,那么它就可以使用
*
运算符来调用其
deref()
方法。所以我认为使用
*
的结果应该与显式调用
deref()
的结果相同。但我发现在某些情况下这两个结果并不相等。例如:

use std::ops::Deref;

fn main() {
    let sth = Box::new(5);
    println!("{:p}", sth.deref());
    println!{"{:?}", *sth};
}

我搜索了文档,知道

deref()
Box
的签名是
(&self)->&T
。这意味着它应该返回内部值的引用。然而,
*sth
看起来像是直接返回内部值。为什么两个结果不相等?

rust dereference
2个回答
4
投票

*
v.deref()
不同(或更准确地说是
Deref::deref(&v)
) - 它更像
*Deref::deref(&v)
(注意
*
)。

具体针对

Box
,它可以移出它,例如:

let s = Box::new(String::new());
let moved_out = *s;
// s; // Error, moved out of the `Box`.

无论哪种类型,它都会创建一个位置 - 它可以是

*Deref::deref(&v)
*DerefMut::deref_mut(&v)
,具体取决于是否需要可变访问。


1
投票

正如 Chayim 回答的那样,

deref()
用于获取对内部项目的引用,
*
然后实际访问该内部项目。

然而,当谈到

Box
时,你不会发现它的行为受到任何特征的调节(至少到目前为止):
Box
是一个语言项目

虽然与引用不同,它看起来像普通类型,但它确实具有相同的地位,并且位于语言本身的核心。因此,它可以(并且确实)以其他类型无法做到的方式运行。

其中一个行为是取消引用的能力,这是它完全独特的(过去已经为此提出了 RFC,但据我所知,进展甚微)。

尽管在您的具体情况下甚至不涉及:

println!
将始终引用其参数,所以

println!{"{:?}", *sth};

确实如此

let args = Args::new(&*sth);

然后你就得到了值,因为有一个毯子

impl Display for &T where T: Display
委托给
T
的实现(顺便说一句,
Box
也是如此)。

您可以通过复制该行来检查它是否工作正常,如果该值已移动(并且该框已删除),则不会出现这种情况。

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