Struct core::marker::PhantomData
[−]
[src]
pub struct PhantomData<T: ?Sized>;
PhantomData<T>`PhantomDataallows you to describe that a type acts as if it stores a value of type` allows you to describe that a type acts as if it stores a value of type T`T`,
even though it does not. This allows you to inform the compiler about certain safety properties
of your code.
Though they both have scary names, PhantomData<T>`PhantomData
Examples
Unused lifetime parameter
Perhaps the most common time that PhantomData`PhantomDatais required is with a struct that has an unused lifetime parameter, typically as part of some unsafe code. For example, here is a struct` is required is
with a struct that has an unused lifetime parameter, typically as
part of some unsafe code. For example, here is a struct Slice`Slicethat has two pointers of type`
that has two pointers of type *const T`*const T`, presumably pointing into
an array somewhere:
struct Slice<'a, T> { start: *const T, end: *const T, }
The intention is that the underlying data is only valid for the
lifetime 'a`'a, so`, so Slice`Sliceshould not outlive` should not outlive 'a`'a. However, this intent is not expressed in the code, since there are no uses of the lifetime`. However, this
intent is not expressed in the code, since there are no uses of
the lifetime 'a`'aand hence it is not clear what data it applies to. We can correct this by telling the compiler to act *as if* the` and hence it is not clear what data it applies
to. We can correct this by telling the compiler to act as if the
Slice`Slicestruct contained a borrowed reference` struct contained a borrowed reference &'a T`&'a T`:
use std::marker::PhantomData; struct Slice<'a, T:'a> { start: *const T, end: *const T, phantom: PhantomData<&'a T> }
This also in turn requires that we annotate T:'a`T:'a, indicating that`, indicating
that T`Tis a type that can be borrowed for the lifetime` is a type that can be borrowed for the lifetime 'a`'a`.
Unused type parameters
It sometimes happens that there are unused type parameters that
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 when handling external resources over a
foreign function interface. PhantomData<T>`PhantomData
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); } }
Indicating ownership
Adding a field of type PhantomData<T>`PhantomDataalso indicates that your struct owns data of type` also indicates that your
struct owns data of type T`T. This in turn implies that when your struct is dropped, it may in turn drop one or more instances of the type`. This in turn implies that when your
struct is dropped, it may in turn drop one or more instances of
the type T`T, though that may not be apparent from the other structure of the type itself. This is commonly necessary if the structure is using an unsafe pointer like`, though that may not be apparent from the other
structure of the type itself. This is commonly necessary if the
structure is using an unsafe pointer like *mut T`*mut Twhose referent may be dropped when the type is dropped, as a` whose referent
may be dropped when the type is dropped, as a *mut T`*mut T` is
otherwise not treated as owned.
If your struct does not in fact own the data of type T`T, it is better to use a reference type, like`, it is
better to use a reference type, like PhantomData<&'a T>`PhantomData<&'a T>(ideally) or`
(ideally) or PhantomData<*const T>`PhantomData<*const T>` (if no lifetime applies), so
as not to indicate ownership.