ps4 - ¿Por qué Rust''s assert_eq! implementado usando un partido?
rust traduccion (1)
De acuerdo, eliminemos la coincidencia.
macro_rules! assert_eq_2 {
($left:expr, $right:expr) => ({
if !($left == $right) {
panic!(r#"assertion failed: `(left == right)`
left: `{:?}`,
right: `{:?}`"#, $left, $right)
}
});
}
Ahora, vamos a elegir un ejemplo completamente al azar ...
fn really_complex_fn() -> i32 {
// Hit the disk, send some network requests,
// and mine some bitcoin, then...
return 1;
}
assert_eq_2!(really_complex_fn(), 1);
Esto se expandiría a ...
{
if !(really_complex_fn() == 1) {
panic!(r#"assertion failed: `(left == right)`
left: `{:?}`,
right: `{:?}`"#, really_complex_fn(), 1)
}
}
Como puede ver, llamamos a la función dos veces . Eso es menos que ideal, más aún si el resultado de la función puede cambiar cada vez que se invoca.
La match
es solo una forma rápida y fácil de evaluar ambos "argumentos" a la macro exactamente una vez y vincularlos a los nombres de las variables.
¡Aquí está el assert_eq!
de Rust assert_eq!
macro implementación . He copiado solo la primera rama por brevedad:
macro_rules! assert_eq {
($left:expr, $right:expr) => ({
match (&$left, &$right) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
panic!(r#"assertion failed: `(left == right)`
left: `{:?}`,
right: `{:?}`"#, left_val, right_val)
}
}
}
});
}
¿Cuál es el propósito del match
aquí? ¿Por qué no es suficiente verificar la falta de igualdad?