es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Interpola `ident` en una literal de cadena en `macro_rules!`

¿Es posible interpolar una variable macro_rules!, de tipo ident, en una cadena literal en una macro? En otras palabras, ¿es posible “escapar” las comillas dobles de la literal?

// <code>trace_macros!</code> requires nightly

<h1>![feature(trace_macros)]</h1>

trace_macros!(true);

macro_rules! export_mod_if_feature {
    ($system:ident) => {
        #[cfg(target_os = "$system")] // <-- el problema está aquí
        pub mod $system;
    };
}

export_mod_if_feature!(linux);

// ... debería traducirse a:

<h1>[cfg(target_os = "linux")]</h1>

pub mod linux;

// ... pero en cambio se convierte en:

<h1>[cfg(target_os = "$system")]</h1>

pub mod linux;

He intentado usar #[cfg(target_os = stringify!($system))] pero cfg requiere una cadena literal real después de target_os =, no solo una cadena en tiempo de compilación.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Sí, es posible interpolar una variable macro_rules!, de tipo ident, en un literal de cadena en una macro. Una manera de lograr esto es usando la macro concat! para combinar la variable con el literal de cadena. Por ejemplo:

    macro_rules! example_macro {
        ($var:ident) => {
            println!("{}", concat!("El valor de ", stringify!($var), " es ", $var));
        };
    }
    
    let x = 42;
    example_macro!(x);
    

    Esto producirá la siguiente salida:

    El valor de x es 42
    

    Nota que la macro stringify! se usa para obtener la representación en cadena del nombre de la variable, y luego se utiliza concat! para combinar esa cadena con la cadena literal.

    En el ejemplo dado en la pregunta, la línea #[cfg(target_os = "$system")] se puede modificar de la siguiente manera para interpolar la variable $system:

    #[cfg(target_os = stringify!($system))]
    

    Esto producirá el resultado deseado de generar código con el atributo target_os configurado con el valor de cadena de $system.

Comments are closed.