Struct core::pin::Pin1.33.0[][src]

#[repr(transparent)]
pub struct Pin<P> { /* fields omitted */ }
Expand description

固定的指针。

这是一种指针的包装,该指针使该指针 “pin” 成为其值,从而防止该指针引用的值被移动,除非它实现 Unpin

有关固定的说明,请参见 pin module 文档。

Implementations

围绕一个指向实现 Unpin 类型的数据的指针,创建一个新的 Pin<P>

Pin::new_unchecked 不同,此方法是安全的,因为指针 P 解引用了 Unpin 类型,从而取消了固定保证。

解包此 Pin<P>,返回基础指针。

这要求该 Pin 内部的数据为 Unpin,以便我们在展开包装时可以忽略固定不变式。

围绕引用可能会或可能不会实现 Unpin 的某些数据,创建一个新的 Pin<P>

如果 pointer 解引用 Unpin 类型,则应改用 Pin::new

Safety

此构造函数是不安全的,因为我们不能保证 pointer 指向的数据是固定的,这意味着在丢弃数据之前,数据将不会移动或存储空间无效。 如果构造的 Pin<P> 不能保证数据 P 指向固定的,则违反了 API 约定,并可能在以后的 (safe) 操作中导致未定义的行为。

通过使用此方法,您正在制作有关 P::DerefP::DerefMut 实现的 promise (如果存在)。 最重要的是,它们一定不能移出 self 参数: Pin::as_mutPin::as_ref 将调用 DerefMut::deref_mutDeref::derefon the 固定指针,并期望这些方法支持固定不变性。 此外,通过调用此方法,不会再移出引用 P 引用的 promise; 特别是,必须不可能先获得 &mut P::Target,然后再移出该引用 (例如,使用 mem::swap)。

例如,在 &'a mut T 上调用 Pin::new_unchecked 是不安全的,因为虽然可以为给定的生命周期 'a 固定 Pin::new_unchecked,但是您无法控制 'a 结束后是否保持固定状态:

use std::mem;
use std::pin::Pin;

fn move_pinned_ref<T>(mut a: T, mut b: T) {
    unsafe {
        let p: Pin<&mut T> = Pin::new_unchecked(&mut a);
        // 这应该意味着指针 `a` 再也无法移动了。
    }
    mem::swap(&mut a, &mut b);
    // `a` 的地址更改为 `b` 的栈插槽,因此即使我们先前已将其固定,`a` 还是被移动了! 我们违反了固定 API 契约。
}
Run

固定后的值必须永远固定 (除非其类型实现 Unpin)。

同样,在 Rc<T> 上调用 Pin::new_unchecked 是不安全的,因为相同数据的别名可能不受固定限制的限制:

use std::rc::Rc;
use std::pin::Pin;

fn move_pinned_rc<T>(mut x: Rc<T>) {
    let pinned = unsafe { Pin::new_unchecked(Rc::clone(&x)) };
    {
        let p: Pin<&T> = pinned.as_ref();
        // 这应该意味着指向者永远不能再移动。
    }
    drop(pinned);
    let content = Rc::get_mut(&mut x).unwrap();
    // 现在,如果 `x` 是唯一的引用,则对上面固定的数据有一个变量引用,就像在上一个示例中看到的那样,我们可以使用它来移动它。
    // 我们违反了固定 API 契约。
 }
Run

从此固定指针获取固定共享引用。

这是从 &Pin<Pointer<T>>Pin<&T> 的通用方法。 这是安全的,因为作为 Pin::new_unchecked 契约的一部分,在创建 Pin<Pointer<T>> 之后,指针无法移动。

“Malicious” Pointer::Deref 的实现同样被 Pin::new_unchecked 的契约所排除。

解包此 Pin<P>,返回基础指针。

Safety

该函数是不安全的。您必须保证在调用此函数后,将继续将指针 P 视为固定指针,以便可以保留 Pin 类型上的不可变变量。 如果使用生成的 P 的代码不能继续维护违反 API 约定的固定不变式,则可能会在以后的 (safe) 操作中导致未定义的行为。

如果基础数据是 Unpin,则应改用 Pin::into_inner

从此固定指针获取固定变量引用。

这是从 &mut Pin<Pointer<T>>Pin<&mut T> 的通用方法。 这是安全的,因为作为 Pin::new_unchecked 契约的一部分,在创建 Pin<Pointer<T>> 之后,指针无法移动。

“Malicious” Pointer::DerefMut 的实现同样被 Pin::new_unchecked 的契约所排除。

当对使用固定类型的函数进行多次调用时,此方法很有用。

Example

use std::pin::Pin;

impl Type {
    fn method(self: Pin<&mut Self>) {
        // 做一点事
    }

    fn call_method_twice(mut self: Pin<&mut Self>) {
        // `method` 消耗 `self`,因此通过 `as_mut` 重新借用 `Pin<&mut Self>`。
        self.as_mut().method();
        self.as_mut().method();
    }
}
Run

为固定的引用后面的内存分配一个新值。

这会覆盖固定的数据,但是没关系: 它的析构函数在被覆盖之前就已运行,因此不会违反固定保证。

通过映射内部值创建一个新的引脚。

例如,如果要获取某字段的 Pin,则可以使用它在一行代码中访问该字段。 但是,这些 “pinning projections” 有一些陷阱。 有关该主题的更多详细信息,请参见 pin module 文档。

Safety

该函数是不安全的。 您必须确保只要参数值不移动,返回的数据就不会移动 (例如,因为它是该值的字段之一),并且还必须确保不会将其移出接收到的参数内部功能。

从大头针获取共享的引用。

这是安全的,因为不可能移出共享引用。 内部可变性似乎存在问题: 实际上,可以将 T&RefCell<T> 中移出。 但是,只要不存在指向相同数据的 Pin<&T>,并且 RefCell<T> 不允许您创建对其内容的固定引用,这也不是问题。

有关更多详细信息,请参见 “pinning projections” 上的讨论。

Note: Pin 还对目标实现 Deref,可用于访问内部值。 但是,Deref 仅提供一个引用,该引用的生命周期与 Pin 的借用时间一样长,而不是 Pin 本身的生命周期。 这种方法可以将 Pin 转换为引用,并具有与原始 Pin 相同的生命周期。

将此 Pin<&mut T> 转换为具有相同生命周期的 Pin<&T>

获取对此 Pin 内部数据的可变引用。

这要求该 Pin 内部的数据为 Unpin

Note: Pin 还对数据实现 DerefMut,可用于访问内部值。 但是,DerefMut 仅提供一个引用,该引用生命周期与 Pin 的借用时间一样长,而不是 Pin 本身的生命周期。

这种方法可以将 Pin 转换为引用,并具有与原始 Pin 相同的生命周期。

获取对此 Pin 内部数据的可变引用。

Safety

该函数是不安全的。 您必须保证在调用此函数时,永远不会将数据移出收到的变量引用中,以便可以保留 Pin 类型的不可变变量。

如果基础数据是 Unpin,则应改用 Pin::get_mut

通过映射内部值创建一个新的引脚。

例如,如果要获取某字段的 Pin,则可以使用它在一行代码中访问该字段。 但是,这些 “pinning projections” 有一些陷阱。 有关该主题的更多详细信息,请参见 pin module 文档。

Safety

该函数是不安全的。 您必须确保只要参数值不移动,返回的数据就不会移动 (例如,因为它是该值的字段之一),并且还必须确保不会将其移出接收到的参数内部功能。

🔬 This is a nightly-only experimental API. (pin_static_ref #78186)

从固定引用中获取固定引用。

这是安全的,因为 T'static 生命周期的借用,而生命周期永远不会结束。

🔬 This is a nightly-only experimental API. (pin_static_ref #78186)

从静态变量引用中获取固定的变量引用。

这是安全的,因为 T'static 生命周期的借用,而生命周期永远不会结束。

Trait Implementations

返回值的副本。 Read more

source 执行复制分配。 Read more

使用给定的格式化程序格式化该值。 Read more

解引用后的结果类型。

解引用值。

可变地解引用该值。

使用给定的格式化程序格式化该值。 Read more

完成时产生的值类型。

尝试将 future 解析为最终值,如果该值尚不可用,请注册当前任务以进行唤醒。 Read more

🔬 This is a nightly-only experimental API. (generator_trait #43122)

此生成器产生的值的类型。 Read more

🔬 This is a nightly-only experimental API. (generator_trait #43122)

此生成器返回的值的类型。 Read more

🔬 This is a nightly-only experimental API. (generator_trait #43122)

恢复此生成器的执行。 Read more

将该值输入给定的 HasherRead more

将这种类型的切片送入给定的 Hasher 中。 Read more

此方法返回 selfother 之间的 OrderingRead more

比较并返回两个值中的最大值。 Read more

比较并返回两个值中的最小值。 Read more

将值限制为一定的时间间隔。 Read more

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

如果存在,则此方法返回 selfother 值之间的顺序。 Read more

此方法测试的内容少于 (对于 selfother),并且由 < 操作员使用。 Read more

此方法测试小于或等于 (对于 selfother),并且由 <= 运算符使用。 Read more

此方法测试大于 (对于 selfother),并且由 > 操作员使用。 Read more

此方法测试是否大于或等于 (对于 selfother),并且由 >= 运算符使用。 Read more

使用给定的格式化程序格式化该值。

🔬 This is a nightly-only experimental API. (async_stream #79024)

流产生的项的类型。

🔬 This is a nightly-only experimental API. (async_stream #79024)

尝试拉出该流的下一个值,如果该值尚不可用,则注册当前任务以进行唤醒,如果流已用尽,则返回 NoneRead more

🔬 This is a nightly-only experimental API. (async_stream #79024)

返回流剩余长度上的边界。 Read more

Auto Trait Implementations

Blanket Implementations

获取 selfTypeIdRead more

从拥有的值中一成不变地借用。 Read more

从拥有的值中借用。 Read more

执行转换。

执行转换。

发生转换错误时返回的类型。

执行转换。

发生转换错误时返回的类型。

执行转换。