@@ -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.
@@ -5211,4 +5211,177 @@ fail.
5211
5211
5212
5212
# Macros
5213
5213
5214
+ One of Rust's most advanced features is its system of ** macro** s. While
5215
+ functions allow you to provide abstractions over values and operations, macros
5216
+ allow you to provide abstractions over syntax. Do you wish Rust had the ability
5217
+ to do something that it can't currently do? You may be able to write a macro
5218
+ to extend Rust's capabilities.
5219
+
5220
+ You've already used one macro extensively: ` println! ` . When we invoke
5221
+ a Rust macro, we need to use the exclamation mark (` ! ` ). There's two reasons
5222
+ that this is true: the first is that it makes it clear when you're using a
5223
+ macro. The second is that macros allow for flexible syntax, and so Rust must
5224
+ be able to tell where a macro starts and ends. The ` !(...) ` helps with this.
5225
+
5226
+ Let's talk some more about ` println! ` . We could have implemented ` println! ` as
5227
+ a function, but it would be worse. Why? Well, what macros allow you to do
5228
+ is write code that generates more code. So when we call ` println! ` like this:
5229
+
5230
+ ``` {rust}
5231
+ let x = 5i;
5232
+ println!("x is: {}", x);
5233
+ ```
5234
+
5235
+ The ` println! ` macro does a few things:
5236
+
5237
+ 1 . It parses the string to find any ` {} ` s
5238
+ 2 . It checks that the number of ` {} ` s matches the number of other arguments.
5239
+ 3 . It generates a bunch of Rust code, taking this in mind.
5240
+
5241
+ What this means is that you get type checking at compile time, because
5242
+ Rust will generate code that takes all of the types into account. If
5243
+ ` println! ` was a function, it could still do this type checking, but it
5244
+ would happen at run time rather than compile time.
5245
+
5246
+ We can check this out using a special flag to ` rustc ` . This code, in a file
5247
+ ` print.rs ` :
5248
+
5249
+ ``` {rust}
5250
+ fn main() {
5251
+ let x = "Hello";
5252
+ println!("x is: {:s}", x);
5253
+ }
5254
+ ```
5255
+
5256
+ Can have its macros expanded like this: ` rustc print.rs --pretty=expanded ` , will
5257
+ give us this huge result:
5258
+
5259
+ ``` {rust,ignore}
5260
+ #![feature(phase)]
5261
+ #![no_std]
5262
+ #![feature(globs)]
5263
+ #[phase(plugin, link)]
5264
+ extern crate std = "std";
5265
+ extern crate rt = "native";
5266
+ use std::prelude::*;
5267
+ fn main() {
5268
+ let x = "Hello";
5269
+ match (&x,) {
5270
+ (__arg0,) => {
5271
+ #[inline]
5272
+ #[allow(dead_code)]
5273
+ static __STATIC_FMTSTR: [::std::fmt::rt::Piece<'static>, ..2u] =
5274
+ [::std::fmt::rt::String("x is: "),
5275
+ ::std::fmt::rt::Argument(::std::fmt::rt::Argument{position:
5276
+ ::std::fmt::rt::ArgumentNext,
5277
+ format:
5278
+ ::std::fmt::rt::FormatSpec{fill:
5279
+ ' ',
5280
+ align:
5281
+ ::std::fmt::rt::AlignUnknown,
5282
+ flags:
5283
+ 0u,
5284
+ precision:
5285
+ ::std::fmt::rt::CountImplied,
5286
+ width:
5287
+ ::std::fmt::rt::CountImplied,},})];
5288
+ let __args_vec =
5289
+ &[::std::fmt::argument(::std::fmt::secret_string, __arg0)];
5290
+ let __args =
5291
+ unsafe {
5292
+ ::std::fmt::Arguments::new(__STATIC_FMTSTR, __args_vec)
5293
+ };
5294
+ ::std::io::stdio::println_args(&__args)
5295
+ }
5296
+ };
5297
+ }
5298
+ ```
5299
+
5300
+ Intense. Here's a trimmed down version that's a bit easier to read:
5301
+
5302
+ ``` {rust,ignore}
5303
+ fn main() {
5304
+ let x = 5i;
5305
+ match (&x,) {
5306
+ (__arg0,) => {
5307
+ static __STATIC_FMTSTR: =
5308
+ [String("x is: "),
5309
+ Argument(Argument {
5310
+ position: ArgumentNext,
5311
+ format: FormatSpec {
5312
+ fill: ' ',
5313
+ align: AlignUnknown,
5314
+ flags: 0u,
5315
+ precision: CountImplied,
5316
+ width: CountImplied,
5317
+ },
5318
+ },
5319
+ ];
5320
+ let __args_vec = &[argument(secret_string, __arg0)];
5321
+ let __args = unsafe { Arguments::new(__STATIC_FMTSTR, __args_vec) };
5322
+
5323
+ println_args(&__args)
5324
+ }
5325
+ };
5326
+ }
5327
+ ```
5328
+
5329
+ Whew! This isn't too terrible. You can see that we still ` let x = 5i ` ,
5330
+ but then things get a little bit hairy. Three more bindings get set: a
5331
+ static format string, an argument vector, and the aruments. We then
5332
+ invoke the ` println_args ` function with the generated arguments.
5333
+
5334
+ This is the code (well, the full version) that Rust actually compiles. You can
5335
+ see all of the extra information that's here. We get all of the type safety and
5336
+ options that it provides, but at compile time, and without needing to type all
5337
+ of this out. This is how macros are powerful. Without them, you would need to
5338
+ type all of this by hand to get a type checked ` println ` .
5339
+
5340
+ For more on macros, please consult [ the Macros Guide] ( guide-macros.html ) .
5341
+ Macros are a very advanced and still slightly experimental feature, but don't
5342
+ require a deep understanding to call, since they look just like functions. The
5343
+ Guide can help you if you want to write your own.
5344
+
5214
5345
# Unsafe
5346
+
5347
+ Finally, there's one more concept that you should be aware in Rust: ` unsafe ` .
5348
+ There are two circumstances where Rust's safety provisions don't work well.
5349
+ The first is when interfacing with C code, and the second is when building
5350
+ certain kinds of abstractions.
5351
+
5352
+ Rust has support for FFI, (which you can read about in the [ FFI
5353
+ Guide] ( guide-ffi.html ) ) but Rust can't guarantee that the C code will be safe,
5354
+ like Rust's will. Therefore, Rust marks such functions with the ` unsafe `
5355
+ keyword, which indicates that the function may not behave properly.
5356
+
5357
+ Second, if you'd like to create some sort of shared-memory data structure, Rust
5358
+ won't allow it, because memory must be owned by a single owner. However, if
5359
+ you're planning on making access to that shared memory safe, such as with a
5360
+ mutex, _ you_ know that it's safe, but Rust can't know. Writing an ` unsafe `
5361
+ block allows you to ask the compiler to trust you. In this case, the _ internal_
5362
+ implementation of the mutex is considered unsafe, but the _ external_ interface
5363
+ we present is safe. This allows it to be effectively used in normal Rust, while
5364
+ being able to implement functionality that the compiler can't double check for
5365
+ us.
5366
+
5367
+ Doesn't an escape hatch undermine the safety of the entire system? Well, if
5368
+ Rust code segfaults, it _ must_ be because of unsafe code somewhere. By
5369
+ annotating exactly where that is, you have a significantly smaller area to
5370
+ search.
5371
+
5372
+ We haven't even talked about any examples here, and that's because I want to
5373
+ emphasize that you should not be writing unsafe code unless you know exactly
5374
+ what you're doing. The vast majority of Rust developers will only interact with
5375
+ it when doing FFI, and advanced library authors may use it to build certain
5376
+ kinds of abstraction.
5377
+
5378
+ # Conclusion
5379
+
5380
+ We covered a lot of ground here. When you've mastered everything in this Guide,
5381
+ you will have a firm grasp of basic Rust development. There's a whole lot more
5382
+ out there, we've just covered the surface. There's tons of topics that you can
5383
+ dig deeper into, and we've built specialized guides for many of them. To learn
5384
+ more, dig into the [ full documentation
5385
+ index] ( http://doc.rust-lang.org/index.html ) .
5386
+
5387
+ Happy hacking!
0 commit comments