Czytam książkę o Rust i zaczynam grać z Rust macros. Wszystkie typy metavariable są tam objaśnione i mają przykłady, z wyjątkiem ostatniego - tt
. Według książki jest to "jedno drzewo tokenów". Jestem ciekawy, co to jest i do czego służy? Czy możesz podać przykład?Co oznacza typ metadanych tt w makrach Rusta?
Odpowiedz
Jest to pojęcie wprowadzone w celu zapewnienia, że wszystko, co jest w makropolecaniu, poprawnie pasuje do par: ()
, []
i {}
.
Na przykład, dla następującego programu:
fn main() {
println!("Hello world!");
}
Token drzewo byłoby:
fn
main
()
- ∅
{ println!("Hello world!"); }
println
!
("Hello world!")
"Hello world!"
;
Tworzy to drzewo, gdzie proste tokeny (fn
, main
itd.) Są liście, a wszystko otoczone ()
, []
lub {}
ma poddrzewa. Zauważ, że (
nie pojawia się sam w drzewie tokena: nie można dopasować (
bez dopasowania odpowiadającego )
.
Na przykład
macro_rules! {
(fn $name:ident $params:tt $body:tt) => { /* … */}
}
dopasuje powyższe działają dzięki $name → main
, $params →()
, $body → { println!("Hello world!"); }
.
Drzewo tokena jest najmniej wymagającym typem metawłaściwym: pasuje do wszystkiego. Jest często używany w makrach, które mają część "nie do końca", a zwłaszcza w makrach, które mają "głowę" i "ogon". Na przykład makra println!
mają gałąź odpowiadającą ($fmt:expr, $($arg:tt)*)
, gdzie $fmt
jest łańcuchem formatu, a $($arg:tt)*
oznacza "cała reszta" i jest po prostu przekazywana do format_args!
. Co oznacza, że println!
nie musi znać faktycznego formatu i wykonywać z nim skomplikowanych dopasowań.
Dzięki za dobre wyjaśnienie i przykład, właśnie to, czego potrzebowałem! –