Struct std::pin::Pin

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

固定的指针。

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

Pin<P> 保证具有与 P 相同的内存布局和 ABI。

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

Implementations§

source§

impl<P> Pin<P>where P: Deref, <P as Deref>::Target: Unpin,

const: unstable · source

pub fn new(pointer: P) -> Pin<P>

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

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

Examples
use std::pin::Pin;

let mut val: u8 = 5;
// 我们可以固定这个值,因为它不关心被移动
let mut pinned: Pin<&mut u8> = Pin::new(&mut val);
Run
1.39.0 (const: unstable) · source

pub fn into_inner(pin: Pin<P>) -> P

解包此 Pin<P>,返回底层指针。

这要求此 Pin 中的数据实现 Unpin,以便我们在展开它时可以忽略固定不,变体。

Examples
use std::pin::Pin;

let mut val: u8 = 5;
let pinned: Pin<&mut u8> = Pin::new(&mut val);
// 解开引脚以获得对值的引用
let r = Pin::into_inner(pinned);
assert_eq!(*r, 5);
Run
source§

impl<P> Pin<P>where P: Deref,

const: unstable · source

pub unsafe fn new_unchecked(pointer: P) -> Pin<P>

围绕引用可能会或可能不会实现 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); // 潜在的 UB ⚠️
    // `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(); // 潜在的 UB ⚠️
    // 现在,如果 `x` 是唯一的引用,则对上面固定的数据有一个变量引用,就像在上一个示例中看到的那样,我们可以使用它来移动它。
    // 我们违反了固定 API 契约。
 }
Run
闭包捕获的置顶

在闭包中使用 Pin::new_unchecked 时需要特别小心: Pin::new_unchecked(&mut var) 其中 var 是按值 (moved) 闭包捕获隐式地使闭包本身被固定的 promise,并且此闭包捕获的所有使用都尊重该固定。

use std::pin::Pin;
use std::task::Context;
use std::future::Future;

fn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) {
    // 创建一个移动 `x` 的闭包,然后在内部以固定的方式使用。
    let mut closure = move || unsafe {
        let _ignore = Pin::new_unchecked(&mut x).poll(cx);
    };
    // 调使用闭包,所以 future 可以假定它已被固定。
    closure();
    // 把封包移到别处。这也动了 `x`!
    let mut moved = closure;
    // 再次调用它意味着我们从两个不同的位置轮询 future,这违反了固定 API 合同。
    moved(); // 潜在的 UB ⚠️
}
Run

将闭包传递给另一个 API 时,它可能会随时移动闭包,因此仅当 API 明确记录闭包已固定时,才能使用闭包捕获上的 Pin::new_unchecked

更好的选择是避免所有这些麻烦,而是在外部函数中固定 (这里使用 pin! 宏) :

use std::pin::pin;
use std::task::Context;
use std::future::Future;

fn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) {
    let mut x = pin!(x);
    // 创建一个捕获 `x: Pin<&mut _>` 的闭包,可以安全移动。
    let mut closure = move || {
        let _ignore = x.as_mut().poll(cx);
    };
    // 调使用闭包,所以 future 可以假定它已被固定。
    closure();
    // 把封包移到别处。
    let mut moved = closure;
    // 在这里再次调用它很好 (除了我们可能正在轮询一个已经返回 `Poll::Ready` 的 future,但这是一个单独的问题)。
    moved();
}
Run
source

pub fn as_ref(&self) -> Pin<&<P as Deref>::Target>

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

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

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

1.39.0 (const: unstable) · source

pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P

解包此 Pin<P>,返回底层指针。

Safety

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

如果底层数据是 Unpin,则应改为使用 Pin::into_inner

source§

impl<P> Pin<P>where P: DerefMut,

source

pub fn as_mut(&mut self) -> Pin<&mut <P as Deref>::Target>

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

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

Pointer::DerefMut 的 “Malicious” 实现同样被 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
source

pub fn set(&mut self, value: <P as Deref>::Target)where <P as Deref>::Target: Sized,

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

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

Example
use std::pin::Pin;

let mut val: u8 = 5;
let mut pinned: Pin<&mut u8> = Pin::new(&mut val);
println!("{}", pinned); // 5
pinned.as_mut().set(10);
println!("{}", pinned); // 10
Run
source§

impl<'a, T> Pin<&'a T>where T: ?Sized,

source

pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U>where F: FnOnce(&T) -> &U, U: ?Sized,

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

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

Safety

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

const: unstable · source

pub fn get_ref(self) -> &'a T

从 pin 中获取共享引用。

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

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

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

source§

impl<'a, T> Pin<&'a mut T>where T: ?Sized,

const: unstable · source

pub fn into_ref(self) -> Pin<&'a T>

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

const: unstable · source

pub fn get_mut(self) -> &'a mut Twhere T: Unpin,

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

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

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

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

const: unstable · source

pub unsafe fn get_unchecked_mut(self) -> &'a mut T

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

Safety

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

如果底层数据是 Unpin,则应改用 Pin::get_mut

source

pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>where F: FnOnce(&mut T) -> &mut U, U: ?Sized,

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

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

Safety

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

source§

impl<T> Pin<&'static T>where T: ?Sized,

1.61.0 (const: unstable) · source

pub fn static_ref(r: &'static T) -> Pin<&'static T>

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

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

source§

impl<'a, P> Pin<&'a mut Pin<P>>where P: DerefMut,

source

pub fn as_deref_mut(self) -> Pin<&'a mut <P as Deref>::Target>

🔬This is a nightly-only experimental API. (pin_deref_mut #86918)

从此嵌套的固定指针获取固定的可变引用。

这是从 Pin<&mut Pin<Pointer<T>>>Pin<&mut T> 的泛型方法。 它是安全的,因为 Pin<Pointer<T>> 的存在确保了指向者 T 在 future 中不能移动,并且该方法不会使指向者移动。

P::DerefMut 的 “Malicious” 实现同样被 Pin::new_unchecked 的契约排除在外。

source§

impl<T> Pin<&'static mut T>where T: ?Sized,

1.61.0 (const: unstable) · source

pub fn static_mut(r: &'static mut T) -> Pin<&'static mut T>

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

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

Trait Implementations§

source§

impl<P> AsyncIterator for Pin<P>where P: DerefMut, <P as Deref>::Target: AsyncIterator,

§

type Item = <<P as Deref>::Target as AsyncIterator>::Item

🔬This is a nightly-only experimental API. (async_iterator #79024)
异步迭代器产生的项的类型。
source§

fn poll_next( self: Pin<&mut Pin<P>>, cx: &mut Context<'_> ) -> Poll<Option<<Pin<P> as AsyncIterator>::Item>>

🔬This is a nightly-only experimental API. (async_iterator #79024)
尝试提取此异步迭代器的下一个值,如果该值尚不可用,则注册当前任务以进行唤醒,如果异步迭代器耗尽,则返回 NoneRead more
source§

fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (async_iterator #79024)
返回异步迭代器剩余长度的界限。 Read more
source§

impl<P> Clone for Pin<P>where P: Clone,

source§

fn clone(&self) -> Pin<P>

返回值的副本。 Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

source 执行复制分配。 Read more
source§

impl<P> Debug for Pin<P>where P: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

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

impl<P> Deref for Pin<P>where P: Deref,

§

type Target = <P as Deref>::Target

解引用后的结果类型。
source§

fn deref(&self) -> &<P as Deref>::Target

解引用值。
source§

impl<P> DerefMut for Pin<P>where P: DerefMut, <P as Deref>::Target: Unpin,

source§

fn deref_mut(&mut self) -> &mut <P as Deref>::Target

可变地解引用该值。
source§

impl<P> Display for Pin<P>where P: Display,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

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

impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>where A: Allocator + 'static, T: ?Sized,

source§

fn from(boxed: Box<T, A>) -> Pin<Box<T, A>>

Box<T> 转换为 Pin<Box<T>>。如果 T 没有实现 Unpin,那么 *boxed 将被固定在内存中并且无法移动。

这种转换不会在堆上分配,而是就地进行。

这也可以通过 Box::into_pin 获得。

使用 <Pin<Box<T>>>::from(Box::new(x)) 构造和固定 Box 也可以使用 Box::pin(x) 更简洁地编写。

如果您已经拥有 Box<T>,或者您正在以与 Box::new 不同的方式构建 (pinned) Box,则此 From 实现很有用。

1.36.0 · source§

impl<P> Future for Pin<P>where P: DerefMut, <P as Deref>::Target: Future,

§

type Output = <<P as Deref>::Target as Future>::Output

完成时产生的值类型。
source§

fn poll( self: Pin<&mut Pin<P>>, cx: &mut Context<'_> ) -> Poll<<Pin<P> as Future>::Output>

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

impl<G, R> Generator<R> for Pin<&mut G>where G: Generator<R> + ?Sized,

§

type Yield = <G as Generator<R>>::Yield

🔬This is a nightly-only experimental API. (generator_trait #43122)
此生成器产生的值的类型。 Read more
§

type Return = <G as Generator<R>>::Return

🔬This is a nightly-only experimental API. (generator_trait #43122)
此生成器返回的值的类型。 Read more
source§

fn resume( self: Pin<&mut Pin<&mut G>>, arg: R ) -> GeneratorState<<Pin<&mut G> as Generator<R>>::Yield, <Pin<&mut G> as Generator<R>>::Return>

🔬This is a nightly-only experimental API. (generator_trait #43122)
恢复此生成器的执行。 Read more
source§

impl<G, R, A> Generator<R> for Pin<Box<G, A>>where G: Generator<R> + ?Sized, A: Allocator + 'static,

§

type Yield = <G as Generator<R>>::Yield

🔬This is a nightly-only experimental API. (generator_trait #43122)
此生成器产生的值的类型。 Read more
§

type Return = <G as Generator<R>>::Return

🔬This is a nightly-only experimental API. (generator_trait #43122)
此生成器返回的值的类型。 Read more
source§

fn resume( self: Pin<&mut Pin<Box<G, A>>>, arg: R ) -> GeneratorState<<Pin<Box<G, A>> as Generator<R>>::Yield, <Pin<Box<G, A>> as Generator<R>>::Return>

🔬This is a nightly-only experimental API. (generator_trait #43122)
恢复此生成器的执行。 Read more
1.41.0 · source§

impl<P> Hash for Pin<P>where P: Deref, <P as Deref>::Target: Hash,

source§

fn hash<H>(&self, state: &mut H)where H: Hasher,

将该值输入给定的 HasherRead more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where H: Hasher, Self: Sized,

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

impl<P> Ord for Pin<P>where P: Deref, <P as Deref>::Target: Ord,

source§

fn cmp(&self, other: &Pin<P>) -> Ordering

此方法返回 selfother 之间的 OrderingRead more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere Self: Sized,

比较并返回两个值中的最大值。 Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere Self: Sized,

比较并返回两个值中的最小值。 Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere Self: Sized + PartialOrd<Self>,

将值限制在某个时间间隔内。 Read more
1.41.0 · source§

impl<P, Q> PartialEq<Pin<Q>> for Pin<P>where P: Deref, Q: Deref, <P as Deref>::Target: PartialEq<<Q as Deref>::Target>,

source§

fn eq(&self, other: &Pin<Q>) -> bool

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

fn ne(&self, other: &Pin<Q>) -> bool

此方法测试 !=。 默认实现几乎总是足够的,并且不应在没有充分理由的情况下被覆盖。
1.41.0 · source§

impl<P, Q> PartialOrd<Pin<Q>> for Pin<P>where P: Deref, Q: Deref, <P as Deref>::Target: PartialOrd<<Q as Deref>::Target>,

source§

fn partial_cmp(&self, other: &Pin<Q>) -> Option<Ordering>

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

fn lt(&self, other: &Pin<Q>) -> bool

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

fn le(&self, other: &Pin<Q>) -> bool

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

fn gt(&self, other: &Pin<Q>) -> bool

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

fn ge(&self, other: &Pin<Q>) -> bool

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

impl<P> Pointer for Pin<P>where P: Pointer,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

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

impl<P, U> CoerceUnsized<Pin<U>> for Pin<P>where P: CoerceUnsized<U>,

source§

impl<P> Copy for Pin<P>where P: Copy,

source§

impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P>where P: DispatchFromDyn<U>,

1.41.0 · source§

impl<P> Eq for Pin<P>where P: Deref, <P as Deref>::Target: Eq,

Auto Trait Implementations§

§

impl<P> RefUnwindSafe for Pin<P>where P: RefUnwindSafe,

§

impl<P> Send for Pin<P>where P: Send,

§

impl<P> Sync for Pin<P>where P: Sync,

§

impl<P> Unpin for Pin<P>where P: Unpin,

§

impl<P> UnwindSafe for Pin<P>where P: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

获取 selfTypeIdRead more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

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

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

从拥有的值中借用。 Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

返回未更改的参数。

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

调用 U::from(self)

也就是说,这种转换是 From<T> for U 实现选择执行的任何操作。

source§

impl<F> IntoFuture for Fwhere F: Future,

§

type Output = <F as Future>::Output

future 完成时将产生的输出。
§

type IntoFuture = F

我们要把它变成哪种 future?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

根据一个值创建一个 future。 Read more
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

获得所有权后的结果类型。
source§

fn to_owned(&self) -> T

从借用的数据创建拥有的数据,通常是通过克隆。 Read more
source§

fn clone_into(&self, target: &mut T)

使用借来的数据来替换拥有的数据,通常是通过克隆。 Read more
source§

impl<T> ToString for Twhere T: Display + ?Sized,

source§

default fn to_string(&self) -> String

将给定值转换为 StringRead more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

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

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。