Red de conocimiento informático - Problemas con los teléfonos móviles - Abreviatura de macro Rust: ¡tomando vec!

Abreviatura de macro Rust: ¡tomando vec!

Las macros de Rust, aquí nos referimos principalmente a macro_rules!, pueden implementar muchas herramientas poderosas, pero después de todo, siguen siendo diferentes de las implementaciones de funciones y requieren algo de atención adicional.

A continuación se muestra un breve análisis de la implementación de std::vec!. Este párrafo requiere que los lectores tengan una comprensión general del uso de vec!.

En primer lugar, #[cfg(not(test))] significa que esta es una macro que solo es útil en modo sin prueba. En otras palabras, el modo de prueba puede usar otra macro. Esta cuestión no se ampliará aquí.

#[macro_export] indica que esta macro se puede utilizar en otras cajas.

Las dos líneas restantes de la etiqueta del encabezado tampoco se interpretan.

vec! Esta macro tiene tres formas. La primera es similar a la definición de una matriz. [0; 10] define una matriz de longitud 10 y cada número es 0. En consecuencia, vec![0; 10] construye un Vec similar.

Curiosamente, los corchetes fuera de los "parámetros" en la definición de macro son paréntesis, pero la mayoría de los ejemplos dados en los documentos de la biblioteca estándar son corchetes. Esto se debe a que las macros de Rust no limitan cuáles son los corchetes de "llamada", e incluso podemos elegir corchetes. La razón por la que se eligen corchetes al llamar a vec! es simplemente para hacer que esta sintaxis sea más similar a la sintaxis de construir una matriz.

La expr en la lista de parámetros se coloca en la posición del tipo de $elem, que es sintácticamente similar al tipo de parámetro de la función Rust. expr significa que $elem debe ser una expresión (Expresión), y hay algunos otros tipos que se pueden usar para parámetros macro. De esto se puede ver que las macros de Rust tienen clasificaciones de tipos básicas, a diferencia de C, donde todos los parámetros son tokens sin tipos.

Otro punto es que el parámetro macro $crate no está en la lista de parámetros, por lo que se puede especular que es un parámetro utilizado para expresar un significado especial. En términos de nombrar este parámetro, debe representar el nombre de la caja actual. vec! por supuesto, se implementa en la caja estándar. Pero std no puede asumir que la persona que usa esta macro también nombró esta caja std. Rust le permite cambiar el nombre de una caja usando la palabra clave as, y $crate debería adaptarse a este cambio de nombre para nuestras macros. Por lo tanto, cuando escribimos macros exportadas fuera de la caja, debemos usar este parámetro cuando queramos acceder a los tipos o métodos dentro de la caja.

La segunda forma no es fácil de leer, pero combinada con la tercera forma, aún podemos adivinar su significado. La segunda forma coincide con llamadas como vec![a, b, c], y la tercera forma coincide con llamadas como vec![a, b, c,]. Con base en este patrón, suponemos que ($($x:expr);*) puede coincidir con la llamada (a; b; c).

En la segunda forma, el uso de parámetros y definiciones de parámetros están básicamente en el mismo formato (solo que sin la definición de tipo). Entonces suponemos que este efecto es solo expandir los parámetros de acuerdo con a, b, c. Pero todavía no entiendo qué es el cuadro [a, b, c]. Según la box_syntax mencionada anteriormente, creo que esta es una nueva sintaxis que aún no es estable.

Se puede ver que la tercera forma llama a la segunda forma. Creo que esta implementación no es nutritiva. Quizás el compilador de Rust deba considerar cómo eliminar esta característica innecesaria.