implementation of pin_mut!人起,有

...
        // Move the value to ensure that it is owned
        let mut $x = $x;
...

go 掉这个代码,原来的$x仍然笼罩在阴影中,所以把$x搬到这里的用意就是"移动价值,确保它被拥有".

然而,我想知道为什么这是必要的?我发现如果我们不能一成不变地借到$x英镑,下面的代码就会触发.

...
        let mut $x = unsafe {
            $crate::core_reexport::pin::Pin::new_unchecked(&mut $x)
        };
...

这个宏的定义不能接受pin_mut!(&mut x).

那么,let mut $x = $x会在什么情况下单独开火呢?

推荐答案

在没有所有权转移的情况下,您可能会遇到麻烦,因为您无法确保无法访问原始值.考虑一下省略它的宏(本质上只是模糊了unsafe呼叫):

use std::pin::Pin;

macro_rules! pin_mut {
    ($($x:ident),* $(,)?) => { $(
        let mut $x = unsafe {
            Pin::new_unchecked(&mut $x)
        };
    )* }
}

宏的ident参数防止了像试图固定*&mut foo这样的恶作剧(所有权转移也会阻止),然而,这并不意味着我们已经完全跟踪了名称$x.此代码将被允许,但不应被允许:

let mut foo = Foo { ... };

{
    pin_mut!(foo);
    let _: Pin<&mut Foo> = foo;
}

// Woops we now have an unprotected Foo when its supposed to be pinned and
// thus can break the guarantees of Pin::new_unchecked
let foo_ref: &mut Foo = &mut foo;

请看它在playground号公路上编译.Pin::new_unchecked个文档中提到了这个场景.

Rust相关问答推荐

计算具有相邻调换且没有插入或删除的序列的距离

如何使用 list 在Rust for Windows中编译?

创建Rust中元对象协议的动态对象 Select /重新分配机制

铁 rust ,我的模块介绍突然遇到了一个问题

习语选项<;T>;到选项<;U>;当T->;U用From定义

Rust wasm 中的 Closure::new 和 Closure::wrap 有什么区别

如何迭代存储在 struct 中的字符串向量而不移动它们?

Rust 中的复合 `HashSet` 操作或如何在 Rust 中获得 `HashSet` 的显式差异/并集

为什么是&mut发送?线程如何在安全的 Rust 中捕获 &mut?

Rust与_有何区别?

当在lambda中通过引用传递时,为什么会出现终身/类型不匹配错误?

如何将参数传递给Rust 的线程?

SDL2 没有在终端键上触发?

使用 HashMap 条目时如何避免字符串键的短暂克隆?

在 Rust 中获得准确时间的正确方法?

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?

如何断言代码不会在测试中编译?

如果返回类型是通用的,我可以返回 &str 输入的一部分吗?

如何在 Rust 中构建一个 str

返回 &str 但不是 String 时,borrow 时间比预期长