@@ -653,6 +653,144 @@ macro_rules! bct {
653
653
Exercise: use macros to reduce duplication in the above definition of the
654
654
` bct! ` macro.
655
655
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
+
656
794
# Procedural macros
657
795
658
796
If Rust's macro system can't do what you need, you may want to write a
0 commit comments