@@ -535,7 +535,7 @@ arguments we pass to functions and macros, if you're passing more than one.
535
535
When you just use the curly braces, Rust will attempt to display the
536
536
value in a meaningful way by checking out its type. If you want to specify the
537
537
format in a more detailed manner, there are a [ wide number of options
538
- available] ( / std/fmt/index.html) . For now, we'll just stick to the default:
538
+ available] ( std/fmt/index.html ) . For now, we'll just stick to the default:
539
539
integers aren't very complicated to print.
540
540
541
541
So, we've cleared up all of the confusion around bindings, with one exception:
@@ -3520,15 +3520,15 @@ out.
3520
3520
In systems programming, pointers are an incredibly important topic. Rust has a
3521
3521
very rich set of pointers, and they operate differently than in many other
3522
3522
languages. They are important enough that we have a specific [ Pointer
3523
- Guide] ( / guide-pointers.html) that goes into pointers in much detail. In fact,
3523
+ Guide] ( guide-pointers.html ) that goes into pointers in much detail. In fact,
3524
3524
while you're currently reading this guide, which covers the language in broad
3525
3525
overview, there are a number of other guides that put a specific topic under a
3526
3526
microscope. You can find the list of guides on the [ documentation index
3527
- page] ( / index.html#guides) .
3527
+ page] ( index.html#guides ) .
3528
3528
3529
3529
In this section, we'll assume that you're familiar with pointers as a general
3530
3530
concept. If you aren't, please read the [ introduction to
3531
- pointers] ( / guide-pointers.html#an-introduction) section of the Pointer Guide,
3531
+ pointers] ( guide-pointers.html#an-introduction ) section of the Pointer Guide,
3532
3532
and then come back here. We'll wait.
3533
3533
3534
3534
Got the gist? Great. Let's talk about pointers in Rust.
@@ -4711,75 +4711,177 @@ fail.
4711
4711
4712
4712
# Macros
4713
4713
4714
- One of Rust's most advanced features is is system of ** macro** s. While
4714
+ One of Rust's most advanced features is its system of ** macro** s. While
4715
4715
functions allow you to provide abstractions over values and operations, macros
4716
4716
allow you to provide abstractions over syntax. Do you wish Rust had the ability
4717
4717
to do something that it can't currently do? You may be able to write a macro
4718
4718
to extend Rust's capabilities.
4719
4719
4720
- You've already used one macro extensively: ` println! ` . When we invoke
4720
+ You've already used one macro extensively: ` println! ` . When we invoke
4721
4721
a Rust macro, we need to use the exclamation mark (` ! ` ). There's two reasons
4722
4722
that this is true: the first is that it makes it clear when you're using a
4723
4723
macro. The second is that macros allow for flexible syntax, and so Rust must
4724
4724
be able to tell where a macro starts and ends. The ` !(...) ` helps with this.
4725
4725
4726
- An example of even more advanced macro usage is in Rust's ` regex ` crate. This
4727
- implements ** regular expressions* for Rust. Regular expressions provide a
4728
- powerful way to determine if a string matches a certain pattern, but they also
4729
- have their own syntax. Therefore, they're a perfect fit for Rust's macros.
4730
-
4731
- Here's an example of using a regular expression in Rust:
4726
+ Let's talk some more about ` println! ` . We could have implemented ` println! ` as
4727
+ a function, but it would be worse. Why? Well, what macros allow you to do
4728
+ is write code that generates more code. So when we call ` println! ` like this:
4732
4729
4733
4730
``` {rust}
4734
- #![feature(phase)]
4735
- #[phase(plugin)]
4736
- extern crate regex_macros;
4737
- extern crate regex;
4731
+ let x = 5i;
4732
+ println!("x is: {}", x);
4733
+ ```
4734
+
4735
+ The ` println! ` macro does a few things:
4736
+
4737
+ 1 . It parses the string to find any ` {} ` s
4738
+ 2 . It checks that the number of ` {} ` s matches the number of other arguments.
4739
+ 3 . It generates a bunch of Rust code, taking this in mind.
4740
+
4741
+ What this means is that you get type checking at compile time, because
4742
+ Rust will generate code that takes all of the types into account. If
4743
+ ` println! ` was a function, it could still do this type checking, but it
4744
+ would happen at run time rather than compile time.
4738
4745
4746
+ We can check this out using a special flag to ` rustc ` . This code, in a file
4747
+ ` print.rs ` :
4748
+
4749
+ ``` {rust}
4739
4750
fn main() {
4740
- let re = regex!(r"^\d{4}-\d{2}-\d{2}$") ;
4741
- println!("Does our expression match? { }", re.is_match("2014-01-01") );
4751
+ let x = "Hello" ;
4752
+ println!("x is: {:s }", x );
4742
4753
}
4743
4754
```
4744
4755
4745
- This will print "Does our expression match? true". Now, we won't learn
4746
- everything there is to know about regular expressions in this tutorial. We can
4747
- consult [ the regex crate's documentation] ( /regex/index.html ) for more on that
4748
- later. For now, here's the important parts:
4756
+ Can have its macros expanded like this: ` rustc print.rs --pretty=expanded ` , will
4757
+ give us this huge result:
4749
4758
4750
- ``` {rust}
4759
+ ``` {rust,ignore }
4751
4760
#![feature(phase)]
4752
- #[phase(plugin)]
4753
- extern crate regex_macros;
4754
- # fn main() {}
4761
+ #![no_std]
4762
+ #![feature(globs)]
4763
+ #[phase(plugin, link)]
4764
+ extern crate std = "std";
4765
+ extern crate rt = "native";
4766
+ use std::prelude::*;
4767
+ fn main() {
4768
+ let x = "Hello";
4769
+ match (&x,) {
4770
+ (__arg0,) => {
4771
+ #[inline]
4772
+ #[allow(dead_code)]
4773
+ static __STATIC_FMTSTR: [::std::fmt::rt::Piece<'static>, ..2u] =
4774
+ [::std::fmt::rt::String("x is: "),
4775
+ ::std::fmt::rt::Argument(::std::fmt::rt::Argument{position:
4776
+ ::std::fmt::rt::ArgumentNext,
4777
+ format:
4778
+ ::std::fmt::rt::FormatSpec{fill:
4779
+ ' ',
4780
+ align:
4781
+ ::std::fmt::rt::AlignUnknown,
4782
+ flags:
4783
+ 0u,
4784
+ precision:
4785
+ ::std::fmt::rt::CountImplied,
4786
+ width:
4787
+ ::std::fmt::rt::CountImplied,},})];
4788
+ let __args_vec =
4789
+ &[::std::fmt::argument(::std::fmt::secret_string, __arg0)];
4790
+ let __args =
4791
+ unsafe {
4792
+ ::std::fmt::Arguments::new(__STATIC_FMTSTR, __args_vec)
4793
+ };
4794
+ ::std::io::stdio::println_args(&__args)
4795
+ }
4796
+ };
4797
+ }
4755
4798
```
4756
4799
4757
- These attributes allow the ` regex_macros ` crate to actually hook in to the
4758
- compiler itself and extend it with the regular expression syntax. Macros
4759
- are serious business!
4800
+ Intense. Here's a trimmed down version that's a bit easier to read:
4760
4801
4761
- Next, let's look at the actual invocation:
4762
-
4763
- ``` {rust}
4764
- # #![feature(phase)]
4765
- # #[phase(plugin)]
4766
- # extern crate regex_macros;
4767
- # extern crate regex;
4768
- # fn main() {
4769
- let re = regex!(r"^\d{4}-\d{2}-\d{2}$");
4770
- # }
4802
+ ``` {rust,ignore}
4803
+ fn main() {
4804
+ let x = 5i;
4805
+ match (&x,) {
4806
+ (__arg0,) => {
4807
+ static __STATIC_FMTSTR: =
4808
+ [String("x is: "),
4809
+ Argument(Argument {
4810
+ position: ArgumentNext,
4811
+ format: FormatSpec {
4812
+ fill: ' ',
4813
+ align: AlignUnknown,
4814
+ flags: 0u,
4815
+ precision: CountImplied,
4816
+ width: CountImplied,
4817
+ },
4818
+ },
4819
+ ];
4820
+ let __args_vec = &[argument(secret_string, __arg0)];
4821
+ let __args = unsafe { Arguments::new(__STATIC_FMTSTR, __args_vec) };
4822
+
4823
+ println_args(&__args)
4824
+ }
4825
+ };
4826
+ }
4771
4827
```
4772
4828
4773
- The ` regex! ` macro allows us to define a macro. inside of the ` () ` s, we have a
4774
- ` r"" ` construct. This is a 'raw' string literal, that does no escaping of its
4775
- contents. This is a Rust feature, not a macros feature. Finally, the rest of
4776
- the insides, which is the regular expression itself. This regular expression
4777
- roughly translates to "four digits, followed by a hypen, followed by two
4778
- digits, followed by a hypen, followed by two digits."
4829
+ Whew! This isn't too terrible. You can see that we still ` let x = 5i ` ,
4830
+ but then things get a little bit hairy. Three more bindings get set: a
4831
+ static format string, an argument vector, and the aruments. We then
4832
+ invoke the ` println_args ` function with the generated arguments.
4833
+
4834
+ This is the code (well, the full version) that Rust actually compiles. You can
4835
+ see all of the extra information that's here. We get all of the type safety and
4836
+ options that it provides, but at compile time, and without needing to type all
4837
+ of this out. This is how macros are powerful. Without them, you would need to
4838
+ type all of this by hand to get a type checked ` println ` .
4779
4839
4780
- For more on macros, please consult [ the Macros Guide] ( / guide-macros.html) .
4781
- Macros are a very advanced and still slightly experimental feature, and don't
4782
- require a deep understanding to use. The Guide can help you if you want to
4783
- write your own.
4840
+ For more on macros, please consult [ the Macros Guide] ( guide-macros.html ) .
4841
+ Macros are a very advanced and still slightly experimental feature, but don't
4842
+ require a deep understanding to call, since they look just like functions. The
4843
+ Guide can help you if you want to write your own.
4784
4844
4785
4845
# Unsafe
4846
+
4847
+ Finally, there's one more concept that you should be aware in Rust: ` unsafe ` .
4848
+ There are two circumstances where Rust's safety provisions don't work well.
4849
+ The first is when interfacing with C code, and the second is when building
4850
+ certain kinds of abstractions.
4851
+
4852
+ Rust has support for FFI, (which you can read about in the [ FFI
4853
+ Guide] ( guide-ffi.html ) ) but Rust can't guarantee that the C code will be safe,
4854
+ like Rust's will. Therefore, Rust marks such functions with the ` unsafe `
4855
+ keyword, which indicates that the function may not behave properly.
4856
+
4857
+ Second, if you'd like to create some sort of shared-memory data structure, Rust
4858
+ won't allow it, because memory must be owned by a single owner. However, if
4859
+ you're planning on making access to that shared memory safe, such as with a
4860
+ mutex, _ you_ know that it's safe, but Rust can't know. Writing an ` unsafe `
4861
+ block allows you to ask the compiler to trust you. In this case, the _ internal_
4862
+ implementation of the mutex is considered unsafe, but the _ external_ interface
4863
+ we present is safe. This allows it to be effectively used in normal Rust, while
4864
+ being able to implement functionality that the compiler can't double check for
4865
+ us.
4866
+
4867
+ Doesn't an escape hatch undermine the safety of the entire system? Well, if
4868
+ Rust code segfaults, it _ must_ be because of unsafe code somewhere. By
4869
+ annotating exactly where that is, you have a significantly smaller area to
4870
+ search.
4871
+
4872
+ We haven't even talked about any examples here, and that's because I want to
4873
+ emphasize that you should not be writing unsafe code unless you know exactly
4874
+ what you're doing. The vast majority of Rust developers will only interact with
4875
+ it when doing FFI, and advanced library authors may use it to build certain
4876
+ kinds of abstraction.
4877
+
4878
+ # Conclusion
4879
+
4880
+ We covered a lot of ground here. When you've mastered everything in this Guide,
4881
+ you will have a firm grasp of basic Rust development. There's a whole lot more
4882
+ out there, we've just covered the surface. There's tons of topics that you can
4883
+ dig deeper into, and we've built specialized guides for many of them. To learn
4884
+ more, dig into the [ full documentation
4885
+ index] ( http://doc.rust-lang.org/index.html ) .
4886
+
4887
+ Happy hacking!
0 commit comments