Struct std::pin::Pin 1.33.0[−][src]
#[repr(transparent)]pub struct Pin<P> { /* fields omitted */ }
Expand description
Implementations
解包此 Pin<P>
,返回基础指针。
这要求该 Pin
内部的数据为 Unpin
,以便我们在展开包装时可以忽略固定不变式。
围绕引用可能会或可能不会实现 Unpin
的某些数据,创建一个新的 Pin<P>
。
如果 pointer
解引用 Unpin
类型,则应改用 Pin::new
。
Safety
此构造函数是不安全的,因为我们不能保证 pointer
指向的数据是固定的,这意味着在丢弃数据之前,数据将不会移动或存储空间无效。
如果构造的 Pin<P>
不能保证数据 P
指向固定的,则违反了 API 约定,并可能在以后的 (safe) 操作中导致未定义的行为。
通过使用此方法,您正在制作有关 P::Deref
和 P::DerefMut
实现的 promise (如果存在)。
最重要的是,它们一定不能移出 self
参数: Pin::as_mut
和 Pin::as_ref
将调用 DerefMut::deref_mut
和 Deref::deref
on 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
该函数是不安全的。 您必须确保只要参数值不移动,返回的数据就不会移动 (例如,因为它是该值的字段之一),并且还必须确保不会将其移出接收到的参数内部功能。
从固定引用中获取固定引用。
这是安全的,因为 T
是 'static
生命周期的借用,而生命周期永远不会结束。
从静态变量引用中获取固定的变量引用。
这是安全的,因为 T
是 'static
生命周期的借用,而生命周期永远不会结束。
Trait Implementations
如果存在,则此方法返回 self
和 other
值之间的顺序。 Read more
流产生的项的类型。