stringify! y assert!
En esta página
stringify! es un macro incorporado que convierte la forma sintáctica
de una expresión en una cadena — no el valor, sino el código que
escribiste. Esto es especialmente útil para mensajes de depuración y
error que muestran qué había en el código, no solo el resultado numérico.
El patrón dbg! a continuación combina stringify! con el valor
evaluado para producir salidas como [dbg] count * 2 = 14:
stringify! incorporado y macro dbg! que muestra el código fuente junto al valor.
// Feature: `stringify!` — converts an expression into a source string
// Syntax: `stringify!(expr)` — built-in macro
// When to use: assert/debug messages that show the original code, not
// just the value. Pairs beautifully with custom macros.
// `stringify!` captures the syntactic form of the expression.
let s = stringify!(1 + 2 * 3)
print(s)
// expected: 1 + 2 * 3
// Works with identifiers, calls, any expression.
let n = stringify!(hello_world)
print(n)
// expected: hello_world
let call = stringify!(foo(1, 2))
print(call)
// expected: foo(1, 2)
// Useful pattern: dbg! shows "expr = value".
macro dbg(x) {
print("[dbg] {stringify!($x)} = {$x}")
}
let count = 7
dbg!(count)
dbg!(count * 2)
dbg!(count > 5)
// expected:
// [dbg] count = 7
// [dbg] count * 2 = 14
// [dbg] count > 5 = true
Con stringify! disponible, es directo construir macros de aserción que
muestren la expresión que falló. assert! aborta con la forma textual
de la condición; assert_eq! muestra los lados izquierdo y derecho por
separado:
assert! y assert_eq! con mensajes de fallo automáticos via stringify!.
// Feature: Practical macros — `assert!` and `expect!`
// Syntax: combines `stringify!` with the expression for rich messages
// When to use: inline tests and validations with syntactic context.
// assert!: aborts if the condition is false, showing the original code.
macro assert(cond) {
if !$cond {
panic("assertion failed: {stringify!($cond)}")
}
}
assert!(1 + 1 == 2)
assert!("zolo".len() == 4)
print("all asserts passed")
// expected: all asserts passed
// assert_eq!: equality with a useful message on failure.
macro assert_eq(actual, expected) {
if $actual != $expected {
panic("assert_eq failed: {stringify!($actual)} != {$expected}, got {$actual}")
}
}
let result = 2 * 21
assert_eq!(result, 42)
print("ok")
// expected: ok
Desafío
Escribe un macro assert_gt!(a, b) que falle con el mensaje
"esperado {stringify!($a)} > {stringify!($b)}, pero {$a} <= {$b}" cuando
a <= b. Pruébalo con assert_gt!(5, 3) (pasa) y assert_gt!(2, 10)
(debe abortar).
Consulta también