Rust: 关于Pin以及move前后分析

一、Pin由来
在Rust中,自引用结构会导致,此变量被move后,其内部自引用的指针指向不改变,从而存在安全隐患 。

注意:Pin是一个struct。UnPin和!UnPin是trait。这个要分清。

二、方案

对原始的自引用结构,如何增加安全性,方案有以下两步:
1、里面加Phantompinned,
2、外面套上Pin,
这样新的结构被move后,可以保证里面的自引用的指针指向的内容正确。

基于以上分析,我们来进行相关验证:

1、验证普通的结构体move前后行为:move的行为会产生什么影响?
2、带自引用结构move前后的行为:是否存在安全隐患?
3、带PhantomPinned自引用结构move前后的行为:是否解决了原先产生的问题?

在行为方面,具体的考察在于指针地址,指针指向内容的变化,是否能揭示相关问题。

三、相关代码

因为不涉及外部库,cargo.toml文件不需要另列。main.rs代码如下:


use std::pin::Pin;
use std::marker::PhantomPinned;

// unpin结构,没有自引用
#[derive(Debug,Default)]
struct Free{
   
    content: String,
}
// unpin结构 =>move后,ptr对应的指针还会指向原来的地址,但不能正确指向content内容
#[derive(Debug)]
struct SelfRef {
   
    content: String,
    _ptr: *const String,//对应content 或者是&String
}
impl SelfRef{
   
    fn default() ->Self{
   
        SelfRef{
   
            content: String::from("hello world!"),
            _ptr: std::ptr::null(),
        }
    }
    fn set_ref_value(&mut self){
   
        self._ptr = & self.content as *const String; 
    }
}
// !unpin结构,通过引入phantompinned,再pin后,SelfRefPinned被move后,_ptr对应指针可以正确指向content
#[derive(Debug)]
struct SelfRefPinned {
   
    content: String,
    _ptr: *const String,//对应content
    _marker: PhantomPinned,
}

impl SelfRefPinned{
   
    fn default() ->Self{
   
        SelfRefPinned{
   
            content: String::from("hello world!"),
            _ptr: std::ptr::null(),
            _marker: PhantomPinned,
        }
    }
   // stack
    fn set_ref_value_by_ref_mut(pinned_obj: Pin<&mut Self>) {
   
        let content_ptr = &pinned_obj.content as *const String;
        let mut_self_ref: &mut SelfRefPinned = unsafe {
    pinned_obj.get_unchecked_mut() };
        mut_self_ref._ptr = content_ptr;
    }
    // heap 
    fn set_ref_value_by_box_pin(mut pinned_obj: Pin<Box<Self>>) -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值