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.

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