gpt4 book ai didi

rust - 当 T 不是副本时,为什么取消引用 Box 不会提示 "moving out of shared reference"?

转载 作者:行者123 更新时间:2023-12-03 07:56:54 24 4
gpt4 key购买 nike

正如标题所述,为什么下面的代码可以编译?

use std::ops::Deref;

struct Foo {}

fn main() {
let b = Box::new(Foo{});

let pb = *b; //works
// let pb = *b.deref(); // error[E0507]: cannot move out of a shared reference
}

对于具有非复制目标的自定义类型,情况并非如此。

use std::ops::Deref;

struct Foo<T> {
p: T,
}

impl<T> Deref for Foo<T> {
type Target = T;

fn deref(&self) -> &<Self as Deref>::Target {
&self.p
}
}

fn main() {
let f = Foo { p: vec![1u8] };

let pf = *f; // error[E0507]: cannot move out of a shared reference
let pf = *f.deref(); // error[E0507]: cannot move out of a shared reference
}

*Box 没有执行 *Box.deref() 吗?

最佳答案

Is *Box not doing *Box.deref()?

不,事实并非如此。这是编译器魔法的情况之一 - Box 类型有点特殊,编译器会特殊对待它。

查看 the Deref implementation for Box给了我们一个非常强烈的暗示,表明有些东西是不同的:

fn deref(&self) -> &T {
&**self
}

如果这是任何其他类型,这将导致无限递归,但 deref 运算符 (*) 在应用于 Box 值时由编译器内部处理。

您可以对盒子进行的特殊操作之一是将其包含的值移出,这会产生销毁盒子并释放其堆分配的副作用。

(此外,不稳定的 Box::into_inner() 关联函数采用 boxed: Self 并简单地返回 *boxed,进一步说明了这一点。)

关于rust - 当 T 不是副本时,为什么取消引用 Box<T> 不会提示 "moving out of shared reference"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75846106/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com