Mat*_* M. 10
在编程中,固定X意味着指示X不要移动.
例如:
Pin
类型的?该Pin
类型的目的是将对象固定在内存中.
它可以获取对象的地址,并保证只要该实例处于Pin
活动状态,该地址将保持有效.
开发它的主要用例是支持Generators.
生成器的想法是编写一个简单的函数,yield
并让编译器自动将此函数转换为状态机.生成器所携带的状态是需要从一次调用到另一次调用的"堆栈"变量.
Pin
设计用于修复的生成器的关键难点在于,生成器可能最终存储对其自己的数据成员之一的引用(毕竟,您可以创建对堆栈值的引用)或对最终由其自己的数据拥有的对象的引用成员(例如,&T
从a获得Box<T>
).
这是自引用结构的子结构,直到现在需要自定义库(和许多unsafe
).自引用结构的问题是,如果结构移动,它包含的引用仍然指向旧的内存.
Pin
显然解决了这个多年前的Rust问题.作为图书馆类型.它创造了额外的保证,只要Pin
存在固定值不能移动.
因此,用法是首先创建所需的结构,随意返回/移动它,然后当您对它在内存中的位置感到满意时,初始化固定引用.
该类型的可能用途之一Pin
是自引用对象;ralfj 的一篇文章提供了一个SelfReferential
结构的示例,如果没有它,该结构将非常复杂:
use std::ptr;
use std::pin::Pin;
use std::marker::PhantomPinned;
struct SelfReferential {
data: i32,
self_ref: *const i32,
_pin: PhantomPinned,
}
impl SelfReferential {
fn new() -> SelfReferential {
SelfReferential { data: 42, self_ref: ptr::null(), _pin: PhantomPinned }
}
fn init(self: Pin<&mut Self>) {
let this : &mut Self = unsafe { self.get_unchecked_mut() };
// Set up self_ref to point to this.data.
this.self_ref = &mut this.data as *const i32;
}
fn read_ref(self: Pin<&Self>) -> Option<i32> {
// Dereference self_ref if it is non-NULL.
Some(unsafe { self.self_ref.as_ref().copied() })
}
}
fn main() {
let mut data: Pin<Box<SelfReferential>> = Box::pin(SelfReferential::new());
data.as_mut().init();
println!("{:?}", data.as_ref().read_ref()); // prints Some(42)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
693 次 |
最近记录: |