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、几种形式

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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章