diff --git a/technology/dev/programming/languages/Rust.md b/technology/dev/programming/languages/Rust.md index ac730d5..8182a15 100644 --- a/technology/dev/programming/languages/Rust.md +++ b/technology/dev/programming/languages/Rust.md @@ -4,7 +4,7 @@ source: https://doc.rust-lang.org/book mime: "text/rust" extension: "rs" obj: concept -rev: 2024-02-13 +rev: 2024-07-17 --- # Rust @@ -655,6 +655,56 @@ mymacro!("Hello", "World"); This macro gets expanded to the code inside the `macro_rules!` section with the provided arguments. For more information on macros, see the [docs](https://doc.rust-lang.org/reference/macros-by-example.html). +Macros work kind of like a match statement. In the matcher, `$ name : fragment-specifier` matches a Rust syntax fragment of the kind specified and binds it to the metavariable `$name`. Valid fragment specifiers are: +- `item`: an Item +- `block`: a BlockExpression +- `stmt`: a Statement without the trailing semicolon (except for item statements that require semicolons) +- `pat_param`: a PatternNoTopAlt +- `pat`: at least any PatternNoTopAlt, and possibly more depending on edition +- `expr`: an Expression +- `ty`: a Type +- `ident`: an IDENTIFIER_OR_KEYWORD or RAW_IDENTIFIER +- `path`: a TypePath style path +- `tt`: a TokenTree (a single token or tokens in matching delimiters (), [], or {}) +- `meta`: an Attr, the contents of an attribute +- `lifetime`: a LIFETIME_TOKEN +- `vis`: a possibly empty Visibility qualifier +- `literal`: matches -?LiteralExpression + +Common Rust Macros: +- `assert!(bool)`: Asserts that a boolean expression is true at runtime. +- `assert_eq!(a, b)`: Asserts that two expressions are equal to each other (using `PartialEq`). +- `assert_ne!(a, b)`: Asserts that two expressions are not equal to each other (using `PartialEq`). +- `debug_assert!(bool)` Asserts that a boolean expression is true at runtime. +- `debug_assert_eq!(a, b)`: Asserts that two expressions are equal to each other. +- `debug_assert_ne!(a, b)`: Asserts that two expressions are not equal to each other. +- `module_path!()`: Expands to a string that represents the current module path. +- `file!()`: Expands to the file name in which it was invoked. +- `line!()`: Expands to the line number on which it was invoked. +- `column!()`: Expands to the column number at which it was invoked. +- `concat!()`: Concatenates literals into a static string slice. +- `cfg!()`: Evaluates boolean combinations of configuration flags at compile-time. +- `compile_error!(msg)`: Causes compilation to fail with the given error message when encountered. +- `panic!()`: Panics the current thread. +- `dbg!()`: Prints and returns the value of a given expression for quick and dirty debugging. +- `env!(var)`: Inspects an environment variable at compile time. +- `option_env!(var)`: Optionally inspects an environment variable at compile time. +- `print!()`: Prints to the standard output. +- `println!()`: Prints to the standard output, with a newline. +- `eprint!()`: Prints to the standard error. +- `eprintln!()`: Prints to the standard error, with a newline. +- `format!()`: Creates a String using interpolation of runtime expressions. +- `write!()`: Writes formatted data into a buffer. +- `writeln!()`: Write formatted data into a buffer, with a newline appended. +- `include!()`: Parses a file as an expression or an item according to the context. +- `include_bytes!()`: Includes a file as a reference to a byte array. +- `include_str!()`: Includes a UTF-8 encoded file as a string. +- `matches!()`: Returns whether the given expression matches the provided pattern. +- `todo!()`: Indicates unfinished code. +- `unimplemented!()`: Indicates unimplemented code by panicking with a message of “not implemented”. +- `unreachable!()`: Indicates unreachable code. +- `vec![]`: Creates a Vec containing the arguments. + ## `unsafe` Rust Rust is focused strongly on safety, but sometimes doing something dangerous is necessary. In this case you can use the `unsafe` keyword. `unsafe` should be used only when needed as it may cause undefinied behaviour, but when debugging you can solely focus on your `unsafe` blocks as all potential dangerous operations are neatly packaged in them.