Rust :PhantomData、PhantomPinned

一、PhantomData
PhantomData这个类型在rust中经常看到,但往往让人感觉到晕,不知道为什么要用到。

简单来说:有一些场合,你表示(marker)拥有它,但并不使用它。
这个可能时生命周期,也可能是一种借用,也可能是包括一种类型。

所在库的路径上,std::marker::PhantomData,从这个你也可感觉到什么意思。

在标准库的说明中,我们可以了解到:

有二个场景下,经常会用到:
1、有没有用到的生命周期参数时(Unused lifetime parameters)
比如,有一个Slice,但是要求他的参数是‘a,但是在参数中,又没有’a来约束。如何办?

struct Slice<'a, T> {
    start: *const T,
    end: *const T,
}

你可以改造成:

use std::marker::PhantomData;

struct Slice<'a, T: 'a> {
    start: *const T,
    end: *const T,
    phantom: PhantomData<&'a T>,
}

这样,Slice就可以明确约定为’a了。

在具体初始化时,PhantomData往往不需要带生命周期参数,如:

fn borrow_vec<'a, T>(vec: &'a Vec<T>) -> Slice<'a, T> {
    let ptr = vec.as_ptr();
    Slice {
        start: ptr,
        end: unsafe { ptr.add(vec.len()) },
        phantom: PhantomData,
    }
}

2、在FFI下,有没有用到的类型参数时(Unused type parameters)

It sometimes happens that you have unused type parameters which indicate what type of data a struct is “tied” to, even though that data is not actually found in the struct itself. Here is an example where this arises with FFI. The foreign interface uses handles of type *mut () to refer to Rust values of different types. We track the Rust type using a phantom type parameter on the struct ExternalResource which wraps a handle.

use std::marker::PhantomData;
use std::mem;

struct ExternalResource<R> {
   resource_handle: *mut (),
   resource_type: PhantomData<R>,
}

impl<R: ResType> ExternalResource<R> {
    fn new() -> ExternalResource<R> {
        let size_of_res = mem::size_of::<R>();
        ExternalResource {
            resource_handle: foreign_lib::new(size_of_res),
            resource_type: PhantomData,
        }
    }

    fn do_stuff(&self, param: ParamType) {
        let foreign_params = convert_params(param);
        foreign_lib::do_stuff(self.resource_handle, foreign_params);
    }
}

3、具体的例子:Context

pub struct Context<'a> {
    waker: &'a Waker,
    // Ensure we future-proof against variance changes by forcing
    // the lifetime to be invariant (argument-position lifetimes
    // are contravariant while return-position lifetimes are
    // covariant).
    _marker: PhantomData<fn(&'a ()) -> &'a ()>,
}

impl<'a> Context<'a> {
    /// Create a new `Context` from a `&Waker`.
    #[inline]
    pub fn from_waker(waker: &'a Waker) -> Self {
        Context {
            waker,
            _marker: PhantomData,
        }
    }
}

4、几种形式

marker: PhantomData<&'a T>,
marker: PhantomData<& T>,
marker: PhantomData<T>,
marker: PhantomData<*mut () >,

二、PhantomPinned
A marker type which does not implement Unpin.
If a type contains a PhantomPinned, it will not implement Unpin by default.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值