Parámetros de tipo fantasma

Un parámetro de tipo fantasma es uno que no aparece en tiempo de ejecución, pero se comprueba estáticamente (y solo) en tiempo de compilación.

Los tipos de datos pueden usar parámetros de tipos genéricos adicionales para actuar como marcadores o para realizar la verificación de tipos en el momento de la compilación. Estos parámetros adicionales no contienen valores de almacenamiento y no tienen comportamiento en tiempo de ejecución.

En el siguiente ejemplo, combinamos std::marker::PhantomData con el concepto de parámetro de tipo fantasma para crear tuplas que contienen diferentes tipos de datos.

use std::marker::PhantomData;

// Una estructura de tupla fantasma genérica sobre `A` con el parámetro oculto `B`
#[derive(PartialEq)] // Permite la prueba de igualdad para este tipo.
struct TuplaFantasma<A, B>(A,PhantomData<B>);

// Una estructura de tipo fantasma genérica sobre `A` con el parámetro oculto `B`
#[derive(PartialEq)] // Permite la prueba de igualdad para este tipo.
struct EstructuraFantasma<A, B> { primer: A, fantasma: PhantomData<B> }

// Nota: El almacenamiento se asigna para el tipo genérico `A`, pero no para `B`.
//      Por lo tanto, `B` no se puede usar en cálculos.

fn main() {
    // Aquí, `f32` y `f64` son los parámetros ocultos.
    // El tipo TuplaFantasma es especificado como `<char, f32>`.
    let _tupla1: TuplaFantasma<char, f32> = TuplaFantasma('Q', PhantomData);
    // El tipo TuplaFantasma es especificado como `<char, f64>`.
    let _tupla2: TuplaFantasma<char, f64> = TuplaFantasma('Q', PhantomData);

    // El tipo es especificado como `<char, f32>`.
    let _estructura1: EstructuraFantasma<char, f32> = EstructuraFantasma {
        primer: 'Q',
        fantasma: PhantomData,
    };
    // El tipo es especifica como `<char, f64>`.
    let _estructura2: EstructuraFantasma<char, f64> = EstructuraFantasma {
        primer: 'Q',
        fantasma: PhantomData,
    };
    
    // ¡Error en tiempo de compilación! No coinciden los tipos, por lo que no se pueden
    // comparar:
    //println!("_tupla1 == _tupla2 produce: {}",
    //          _tupla1 == _tupla2);
    
    // ¡Error en tiempo de compilación! No coinciden los tipos, por lo que no se pueden
    // comparar:
    //println!("_estructura1 == _estructura2 produce: {}",
    //          _estructura1 == _estructura2);
}

Ve también

Derive y Estructuras