Skip to content

Commit ed9dbce

Browse files
committed
Add common macros to TRPL
Fixes #22621
1 parent 5576b05 commit ed9dbce

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

src/doc/trpl/macros.md

+138
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,144 @@ macro_rules! bct {
653653
Exercise: use macros to reduce duplication in the above definition of the
654654
`bct!` macro.
655655

656+
# Common macros
657+
658+
Here are some common macros you’ll see in Rust code.
659+
660+
## panic!
661+
662+
This macro causes the current thread to panic. You can give it a message
663+
to panic with:
664+
665+
```rust,ignore
666+
panic!("oh no!");
667+
```
668+
669+
## unreachable!
670+
671+
This macro is used when you think some code should never execute:
672+
673+
```rust
674+
if false {
675+
unreachable!();
676+
}
677+
```
678+
679+
Sometimes, the compiler may make you have a different branch that you know
680+
will never, ever run. In these cases, use this macro, so that if you end
681+
up wrong, you’ll get a `panic!` about it.
682+
683+
```rust
684+
let x: Option<i32> = None;
685+
686+
match x {
687+
Some(_) => unreachable!(),
688+
None => println!("I know x is None!"),
689+
}
690+
```
691+
692+
## unimplemented!
693+
694+
The `unimplemented!` macro can be used when you’re trying to get your functions
695+
to typecheck, and don’t want to worry about writing out the body of the
696+
function. For example, let’s say we have some program, but it isn’t compiling
697+
due to a type error, and we can’t figure out why. When we ask someone
698+
for help, we just care about the types, not what the bodies do, so we can
699+
give them something like this:
700+
701+
```rust,ignore
702+
fn foo(i: i32) -> i32 {
703+
unimplemented!();
704+
}
705+
706+
let x: i64 = 100;
707+
708+
foo(x);
709+
```
710+
711+
which of course errors:
712+
713+
```text
714+
715+
error: mismatched types:
716+
expected `i32`,
717+
found `i64`
718+
(expected i32,
719+
found i64) [E0308]
720+
8 foo(x);
721+
^
722+
```
723+
724+
Our real `foo()` function could be hundreds of lines, but that’s not what
725+
the problem is. This lets us simplify it. We’d need to give it a real body
726+
before it’s done, of course...
727+
728+
## vec!
729+
730+
The `vec!` macro is used throughout the book, so you’ve probably seen it
731+
already. It creates `Vec<T>`s with ease:
732+
733+
```rust
734+
let v = vec![1, 2, 3, 4, 5];
735+
```
736+
737+
It also lets you make vectors with repeating values. For example, a hundred
738+
zeroes:
739+
740+
```rust
741+
let v = vec![0; 100];
742+
```
743+
744+
## assert! and assert_eq!
745+
746+
These two macros are used in tests. `assert!` takes a boolean, and `assert_eq!`
747+
takes two values and compares them. Truth passes, success `panic!`s. Like
748+
this:
749+
750+
```rust,ignore
751+
// A-ok!
752+
753+
assert!(true);
754+
assert_eq!(5, 3 + 2);
755+
756+
// nope :(
757+
758+
assert!(5 < 3);
759+
assert_eq!(5, 3);
760+
```
761+
## try!
762+
763+
`try!` is used for error handling. It takes something that can return a
764+
`Result<T, E>`, and gives `T` if it’s a `Ok<T>`, and `return`s with the
765+
`Err(E)` if it’s that. Like this:
766+
767+
```rust,ignore
768+
use std::fs::File;
769+
770+
fn foo() -> std::io::Result<()> {
771+
let f = try!(File::create("foo.txt"));
772+
773+
Ok(())
774+
}
775+
```
776+
777+
This is cleaner than doing this:
778+
779+
```rust,ignore
780+
use std::fs::File;
781+
782+
fn foo() -> std::io::Result<()> {
783+
let f = File::create("foo.txt");
784+
785+
let f = match f {
786+
Ok(t) => t,
787+
Err(e) => return Err(e),
788+
};
789+
790+
Ok(())
791+
}
792+
```
793+
656794
# Procedural macros
657795

658796
If Rust's macro system can't do what you need, you may want to write a

0 commit comments

Comments
 (0)