解除引用Box <T>返回值而不是引用

Man*_*our 4 rust

我似乎无法弄清楚原因:

let a = Box::new(5i32);
let _:() = *a;
Run Code Online (Sandbox Code Playgroud)

告诉我,第二行的指定类型是,i32而不是&i32因为Deref.deref()(我假设被调用*a),返回&T.

另外,如果我打电话给deref()自己:

let _:() = <Box<i32> as Deref>::deref(&a);
Run Code Online (Sandbox Code Playgroud)

我得到了预期&i32.

She*_*ter 8

*foo和打电话不一样foo.deref().如果是的话,你永远无法实际取消引用一个值.^ _ ^

*是"呼叫Deref::deref,然后进入提供的地址"的语法糖.这正是人们对该运营商的期望.Deref存在使其可扩展.

最后一点掩盖了一些细节,这些细节使得"答案"的覆盖范围要好得多.


blu*_*uss 7

解除引用不一定产生(中间)值.考虑

let b = Box::new(1);
(*b).clone();
Run Code Online (Sandbox Code Playgroud)

i32::clone()使用&self参数调用该方法,其中引用指向框内的值,而不是可以生成的临时值(*b).

特征Deref是实现解除引用的一部分(就像DerefMut).

*盒子上可以另外做什么没有相应的特性:移出内部值并丢弃盒子; 这是俗称的,DerefMove但在这一点上仍然是编译器硬编码的盒子专业.

当编译器看到时(*a),它必须推断是否使用Deref,DerefMut或" DerefMove"; 它是从表达式的使用方式推断出来的:例如,如果&self在结果上调用方法,Deref则使用它.

编辑:固有的可复制类型(特征Copy),使用Deref后跟副本而不是" DerefMove"; 然后,这不再是Box的适用,但适用于所有智能指针.