新提出的Pin类型有哪些用例?

00i*_*j00 14 reference rust

Pin不稳定的Rust中有一个新类型,RFC已经合并.据说传递引用时它被称为游戏改变者,但我不确定如何以及何时应该使用它.

任何人都可以用外行的话来解释它吗?

Mat*_* M. 10

什么是钉扎?

在编程中,固定X意味着指示X不要移动.

例如:

  • 将线程固定到CPU内核,以确保它始终在同一CPU上执行,
  • 固定内存中的对象,以防止垃圾收集器移动它(例如在C#中).

有什么Pin类型的?

Pin类型的目的是将对象固定在内存中.

它可以获取对象的地址,并保证只要该实例处于Pin活动状态,该地址将保持有效.

有什么用途?

开发它的主要用例是支持Generators.

生成器的想法是编写一个简单的函数,yield并让编译器自动将此函数转换为状态机.生成器所携带的状态是需要从一次调用到另一次调用的"堆栈"变量.

Pin设计用于修复的生成器的关键难点在于,生成器可能最终存储对其自己的数据成员之一的引用(毕竟,您可以创建对堆栈值的引用)或对最终由其自己的数据拥有的对象的引用成员(例如,&T从a获得Box<T>).

这是自引用结构的子结构,直到现在需要自定义库(和许多unsafe).自引用结构的问题是,如果结构移动,它包含的引用仍然指向旧的内存.

Pin显然解决了这个多年前的Rust问题.作为图书馆类型.它创造了额外的保证,只要Pin存在固定值不能移动.

因此,用法是首先创建所需的结构,随意返回/移动它,然后当您对它在内存中的位置感到满意时,初始化固定引用.


lje*_*drz 5

该类型的可能用途之一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)