mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
auto merge of #11364 : brson/rust/docs, r=alexcrichton
This reorganizes the documentation index to be more focused on the in-tree docs, and to clean up the style, and it also adds @steveklabnik's pointer guide.
This commit is contained in:
commit
aa1839bd69
3
configure
vendored
3
configure
vendored
@ -801,7 +801,8 @@ do
|
||||
make_dir $h/test/doc-tutorial
|
||||
make_dir $h/test/doc-guide-ffi
|
||||
make_dir $h/test/doc-guide-macros
|
||||
make_dir $h/test/doc-guide-borrowed-ptr
|
||||
make_dir $h/test/doc-guide-lifetimes
|
||||
make_dir $h/test/doc-guide-pointers
|
||||
make_dir $h/test/doc-guide-container
|
||||
make_dir $h/test/doc-guide-tasks
|
||||
make_dir $h/test/doc-guide-conditions
|
||||
|
482
doc/guide-pointers.md
Normal file
482
doc/guide-pointers.md
Normal file
@ -0,0 +1,482 @@
|
||||
% The Rust Pointer Guide
|
||||
|
||||
Rust's pointers are one of its more unique and compelling features. Pointers
|
||||
are also one of the more confusing topics for newcomers to Rust. They can also
|
||||
be confusing for people coming from other languages that support pointers, such
|
||||
as C++. This tutorial will help you understand this important topic.
|
||||
|
||||
# You don't actually need pointers
|
||||
|
||||
I have good news for you: you probably don't need to care about pointers,
|
||||
especially as you're getting started. Think of it this way: Rust is a language
|
||||
that emphasizes safety. Pointers, as the joke goes, are very pointy: it's easy
|
||||
to accidentally stab yourself. Therefore, Rust is made in a way such that you
|
||||
don't need them very often.
|
||||
|
||||
"But tutorial!" you may cry. "My co-worker wrote a function that looks like
|
||||
this:
|
||||
|
||||
~~~rust
|
||||
fn succ(x: &int) -> int { *x + 1 }
|
||||
~~~
|
||||
|
||||
So I wrote this code to try it out:
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
fn main() {
|
||||
let number = 5;
|
||||
let succ_number = succ(number);
|
||||
println!("{}", succ_number);
|
||||
}
|
||||
~~~
|
||||
|
||||
And now I get an error:
|
||||
|
||||
~~~ {.notrust}
|
||||
error: mismatched types: expected `&int` but found `<VI0>` (expected &-ptr but found integral variable)
|
||||
~~~
|
||||
|
||||
What gives? It needs a pointer! Therefore I have to use pointers!"
|
||||
|
||||
Turns out, you don't. All you need is a reference. Try this on for size:
|
||||
|
||||
~~~rust
|
||||
# fn succ(x: &int) -> int { *x + 1 }
|
||||
fn main() {
|
||||
let number = 5;
|
||||
let succ_number = succ(&number);
|
||||
println!("{}", succ_number);
|
||||
}
|
||||
~~~
|
||||
|
||||
It's that easy! One extra little `&` there. This code will run, and print `6`.
|
||||
|
||||
That's all you need to know. Your co-worker could have written the function
|
||||
like this:
|
||||
|
||||
~~~rust
|
||||
fn succ(x: int) -> int { x + 1 }
|
||||
|
||||
fn main() {
|
||||
let number = 5;
|
||||
let succ_number = succ(number);
|
||||
println!("{}", succ_number);
|
||||
}
|
||||
~~~
|
||||
|
||||
No pointers even needed. Then again, this is a simple example. I assume that
|
||||
your real-world `succ` function is more complicated, and maybe your co-worker
|
||||
had a good reason for `x` to be a pointer of some kind. In that case, references
|
||||
are your best friend. Don't worry about it, life is too short.
|
||||
|
||||
However.
|
||||
|
||||
Here are the use-cases for pointers. I've prefixed them with the name of the
|
||||
pointer that satisfies that use-case:
|
||||
|
||||
1. Owned: ~Trait must be a pointer, becuase you don't know the size of the
|
||||
object, so indirection is mandatory.
|
||||
2. Owned: You need a recursive data structure. These can be infinite sized, so
|
||||
indirection is mandatory.
|
||||
3. Owned: A very, very, very rare situation in which you have a *huge* chunk of
|
||||
data that you wish to pass to many methods. Passing a pointer will make this
|
||||
more efficient. If you're coming from another language where this technique is
|
||||
common, such as C++, please read "A note..." below.
|
||||
4. Managed: Having only a single owner to a piece of data would be inconvenient
|
||||
or impossible. This is only often useful when a program is very large or very
|
||||
complicated. Using a managed pointer will activate Rust's garbage collection
|
||||
mechanism.
|
||||
5: Borrowed: You're writing a function, and you need a pointer, but you don't
|
||||
care about its ownership. If you make the argument a borrowed pointer, callers
|
||||
can send in whatever kind they want.
|
||||
|
||||
Five exceptions. That's it. Otherwise, you shouldn't need them. Be skeptical
|
||||
of pointers in Rust: use them for a deliberate purpose, not just to make the
|
||||
compiler happy.
|
||||
|
||||
## A note for those proficient in pointers
|
||||
|
||||
If you're coming to Rust from a language like C or C++, you may be used to
|
||||
passing things by reference, or passing things by pointer. In some langauges,
|
||||
like Java, you can't even have objects without a pointer to them. Therefore, if
|
||||
you were writing this Rust code:
|
||||
|
||||
~~~rust
|
||||
# fn transform(p: Point) -> Point { p }
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p0 = Point { x: 5, y: 10};
|
||||
let p1 = transform(p0);
|
||||
println!("{:?}", p1);
|
||||
}
|
||||
|
||||
~~~
|
||||
|
||||
I think you'd implement `transform` like this:
|
||||
|
||||
~~~rust
|
||||
# struct Point {
|
||||
# x: int,
|
||||
# y: int,
|
||||
# }
|
||||
# let p0 = Point { x: 5, y: 10};
|
||||
fn transform(p: &Point) -> Point {
|
||||
Point { x: p.x + 1, y: p.y + 1}
|
||||
}
|
||||
|
||||
// and change this:
|
||||
let p1 = transform(&p0);
|
||||
~~~
|
||||
|
||||
This does work, but you don't need to create those references! The better way to write this is simply:
|
||||
|
||||
~~~rust
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
}
|
||||
|
||||
fn transform(p: Point) -> Point {
|
||||
Point { x: p.x + 1, y: p.y + 1}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p0 = Point { x: 5, y: 10};
|
||||
let p1 = transform(p0);
|
||||
println!("{:?}", p1);
|
||||
}
|
||||
~~~
|
||||
|
||||
But won't this be inefficent? Well, that's a complicated question, but it's
|
||||
important to know that Rust, like C and C++, store aggregate data types
|
||||
'unboxed,' whereas languages like Java and Ruby store these types as 'boxed.'
|
||||
For smaller structs, this way will be more efficient. For larger ones, it may
|
||||
be less so. But don't reach for that pointer until you must! Make sure that the
|
||||
struct is large enough by performing some tests before you add in the
|
||||
complexity of pointers.
|
||||
|
||||
# Owned Pointers
|
||||
|
||||
Owned pointers are the conceptually simplest kind of pointer in Rust. A rough
|
||||
approximation of owned pointers follows:
|
||||
|
||||
1. Only one owned pointer may exist to a particular place in memory. It may be
|
||||
borrowed from that owner, however.
|
||||
2. The Rust compiler uses static analysis to determine where the pointer is in
|
||||
scope, and handles allocating and de-allocating that memory. Owned pointers are
|
||||
not garbage collected.
|
||||
|
||||
These two properties make for three use cases.
|
||||
|
||||
## References to Traits
|
||||
|
||||
Traits must be referenced through a pointer, becuase the struct that implements
|
||||
the trait may be a different size than a different struct that implements the
|
||||
trait. Therefore, unboxed traits don't make any sense, and aren't allowed.
|
||||
|
||||
## Recursive Data Structures
|
||||
|
||||
Sometimes, you need a recursive data structure. The simplest is known as a 'cons list':
|
||||
|
||||
~~~rust
|
||||
enum List<T> {
|
||||
Nil,
|
||||
Cons(T, ~List<T>),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let list: List<int> = Cons(1, ~Cons(2, ~Cons(3, ~Nil)));
|
||||
println!("{:?}", list);
|
||||
}
|
||||
~~~
|
||||
|
||||
This prints:
|
||||
|
||||
~~~ {.notrust}
|
||||
Cons(1, ~Cons(2, ~Cons(3, ~Nil)))
|
||||
~~~
|
||||
|
||||
The inner lists _must_ be an owned pointer, becuase we can't know how many
|
||||
elements are in the list. Without knowing the length, we don't know the size,
|
||||
and therefore require the indirection that pointers offer.
|
||||
|
||||
## Efficiency
|
||||
|
||||
This should almost never be a concern, but because creating an owned pointer
|
||||
boxes its value, it therefore makes referring to the value the size of the box.
|
||||
This may make passing an owned pointer to a function less expensive than
|
||||
passing the value itself. Don't worry yourself with this case until you've
|
||||
proved that it's an issue through benchmarks.
|
||||
|
||||
For example, this will work:
|
||||
|
||||
~~~rust
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Point { x: 10, y: 20 };
|
||||
do spawn {
|
||||
println(a.x.to_str());
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
This struct is tiny, so it's fine. If `Point` were large, this would be more
|
||||
efficient:
|
||||
|
||||
~~~rust
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = ~Point { x: 10, y: 20 };
|
||||
do spawn {
|
||||
println(a.x.to_str());
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Now it'll be copying a pointer-sized chunk of memory rather than the whole
|
||||
struct.
|
||||
|
||||
# Managed Pointers
|
||||
|
||||
Managed pointers, notated by an `@`, are used when having a single owner for
|
||||
some data isn't convenient or possible. This generally happens when your
|
||||
program is very large and complicated.
|
||||
|
||||
For example, let's say you're using an owned pointer, and you want to do this:
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = ~Point { x: 10, y: 20 };
|
||||
let b = a;
|
||||
println(b.x.to_str());
|
||||
println(a.x.to_str());
|
||||
}
|
||||
~~~
|
||||
|
||||
You'll get this error:
|
||||
|
||||
~~~ {.notrust}
|
||||
test.rs:10:12: 10:13 error: use of moved value: `a`
|
||||
test.rs:10 println(a.x.to_str());
|
||||
^
|
||||
test.rs:8:8: 8:9 note: `a` moved here because it has type `~Point`, which is moved by default (use `ref` to override)
|
||||
test.rs:8 let b = a;
|
||||
^
|
||||
~~~
|
||||
|
||||
As the message says, owned pointers only allow for one owner at a time. When you assign `a` to `b`, `a` becomes invalid. Change your code to this, however:
|
||||
|
||||
~~~rust
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = @Point { x: 10, y: 20 };
|
||||
let b = a;
|
||||
println(b.x.to_str());
|
||||
println(a.x.to_str());
|
||||
}
|
||||
~~~
|
||||
|
||||
And it works:
|
||||
|
||||
~~~ {.notrust}
|
||||
10
|
||||
10
|
||||
~~~
|
||||
|
||||
So why not just use managed pointers everywhere? There are two big drawbacks to
|
||||
managed pointers:
|
||||
|
||||
1. They activate Rust's garbage collector. Other pointer types don't share this
|
||||
drawback.
|
||||
2. You cannot pass this data to another task. Shared ownership across
|
||||
concurrency boundaries is the source of endless pain in other langauges, so
|
||||
Rust does not let you do this.
|
||||
|
||||
# Borrowed Pointers
|
||||
|
||||
Borrowed pointers are the third major kind of pointer Rust supports. They are
|
||||
simultaneously the simplest and the most complicated kind. Let me explain:
|
||||
they're called 'borrowed' pointers because they claim no ownership over the
|
||||
data they're pointing to. They're just borrowing it for a while. So in that
|
||||
sense, they're simple: just keep whatever ownership the data already has. For
|
||||
example:
|
||||
|
||||
~~~rust
|
||||
use std::num::sqrt;
|
||||
|
||||
struct Point {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
fn compute_distance(p1: &Point, p2: &Point) -> f32 {
|
||||
let x_d = p1.x - p2.x;
|
||||
let y_d = p1.y - p2.y;
|
||||
|
||||
sqrt(x_d * x_d + y_d * y_d)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let origin = @Point { x: 0.0, y: 0.0 };
|
||||
let p1 = ~Point { x: 5.0, y: 3.0 };
|
||||
|
||||
println!("{:?}", compute_distance(origin, p1));
|
||||
}
|
||||
~~~
|
||||
|
||||
This prints `5.83095189`. You can see that the `compute_distance` function
|
||||
takes in two borrowed pointers, but we give it a managed and unique pointer. Of
|
||||
course, if this were a real program, we wouldn't have any of these pointers,
|
||||
they're just there to demonstrate the concepts.
|
||||
|
||||
So how is this hard? Well, because we're igorning ownership, the compiler needs
|
||||
to take great care to make sure that everything is safe. Despite their complete
|
||||
safety, a borrowed pointer's representation at runtime is the same as that of
|
||||
an ordinary pointer in a C program. They introduce zero overhead. The compiler
|
||||
does all safety checks at compile time.
|
||||
|
||||
This theory is called 'region pointers,' and involve a concept called
|
||||
'lifetimes'. Here's the simple explanation: would you expect this code to
|
||||
compile?
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
fn main() {
|
||||
println(x.to_str());
|
||||
let x = 5;
|
||||
}
|
||||
~~~
|
||||
|
||||
Probably not. That's becuase you know that the name `x` is valid from where
|
||||
it's declared to when it goes out of scope. In this case, that's the end of
|
||||
the `main` function. So you know this code will cause an error. We call this
|
||||
duration a 'lifetime'. Let's try a more complex example:
|
||||
|
||||
~~~rust
|
||||
fn main() {
|
||||
let mut x = ~5;
|
||||
if(*x < 10) {
|
||||
let y = &x;
|
||||
println!("Oh no: {:?}", y);
|
||||
return;
|
||||
}
|
||||
*x = *x - 1;
|
||||
println!("Oh no: {:?}", x);
|
||||
}
|
||||
~~~
|
||||
|
||||
Here, we're borrowing a pointer to `x` inside of the `if`. The compiler, however,
|
||||
is able to determine that that pointer will go out of scope without `x` being
|
||||
mutated, and therefore, lets us pass. This wouldn't work:
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
fn main() {
|
||||
let mut x = ~5;
|
||||
if(*x < 10) {
|
||||
let y = &x;
|
||||
*x = *x - 1;
|
||||
|
||||
println!("Oh no: {:?}", y);
|
||||
return;
|
||||
}
|
||||
*x = *x - 1;
|
||||
println!("Oh no: {:?}", x);
|
||||
}
|
||||
~~~
|
||||
|
||||
It gives this error:
|
||||
|
||||
~~~ {.notrust}
|
||||
test.rs:5:8: 5:10 error: cannot assign to `*x` because it is borrowed
|
||||
test.rs:5 *x = *x - 1;
|
||||
^~
|
||||
test.rs:4:16: 4:18 note: borrow of `*x` occurs here
|
||||
test.rs:4 let y = &x;
|
||||
^~
|
||||
~~~
|
||||
|
||||
As you might guess, this kind of analysis is complex for a human, and therefore
|
||||
hard for a computer, too! There is an entire [tutorial devoted to borrowed
|
||||
pointers and lifetimes](tutorial-lifetimes.html) that goes into lifetimes in
|
||||
great detail, so if you want the full details, check that out.
|
||||
|
||||
# Returning Pointers
|
||||
|
||||
We've talked a lot about funtions that accept various kinds of pointers, but
|
||||
what about returning them? Here's the rule of thumb: only return a unique or
|
||||
managed pointer if you were given one in the first place.
|
||||
|
||||
What does that mean? Don't do this:
|
||||
|
||||
~~~rust
|
||||
fn foo(x: ~int) -> ~int {
|
||||
return ~*x;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = ~5;
|
||||
let y = foo(x);
|
||||
}
|
||||
~~~
|
||||
|
||||
Do this:
|
||||
|
||||
~~~rust
|
||||
fn foo(x: ~int) -> int {
|
||||
return *x;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = ~5;
|
||||
let y = ~foo(x);
|
||||
}
|
||||
~~~
|
||||
|
||||
This gives you flexibility, without sacrificing performance. For example, this will
|
||||
also work:
|
||||
|
||||
~~~rust
|
||||
fn foo(x: ~int) -> int {
|
||||
return *x;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = ~5;
|
||||
let y = @foo(x);
|
||||
}
|
||||
~~~
|
||||
|
||||
You may think that this gives us terrible performance: return a value and then
|
||||
immediately box it up?!?! Isn't that the worst of both worlds? Rust is smarter
|
||||
than that. There is no copy in this code. `main` allocates enough room for the
|
||||
`@int`, passes it into `foo` as `x`, and then `foo` writes the value into the
|
||||
new box. This writes the return value directly into the allocated box.
|
||||
|
||||
This is important enough that it bears repeating: pointers are not for optimizing
|
||||
returning values from your code. Allow the caller to choose how they want to
|
||||
use your output.
|
||||
|
||||
|
||||
# Related Resources
|
||||
|
||||
* [Lifetimes tutorial](tutorial-lifetimes.html)
|
180
doc/index.md
180
doc/index.md
@ -1,157 +1,45 @@
|
||||
% Rust documentation
|
||||
|
||||
# Reference docs
|
||||
<!-- Completely hide the TOC and the section numbers -->
|
||||
<style type="text/css">
|
||||
#TOC { display: none; }
|
||||
.header-section-number { display: none; }
|
||||
</style>
|
||||
|
||||
**Current (0.9)**
|
||||
[The Rust tutorial](tutorial.html)
|
||||
[The Rust reference manual](rust.html) ([PDF](rust.pdf))
|
||||
|
||||
* [Tutorial](http://doc.rust-lang.org/doc/0.9/tutorial.html)
|
||||
* Guides
|
||||
* [borrowed pointers](http://doc.rust-lang.org/doc/0.9/guide-borrowed-ptr.html)
|
||||
* [conditions](http://doc.rust-lang.org/doc/0.9/guide-conditions.html)
|
||||
* [containers & iterators](http://doc.rust-lang.org/doc/0.9/guide-container.html)
|
||||
* [ffi](http://doc.rust-lang.org/doc/0.9/guide-ffi.html)
|
||||
* [macros](http://doc.rust-lang.org/doc/0.9/guide-macros.html)
|
||||
* [rustpkg](http://doc.rust-lang.org/doc/0.9/guide-rustpkg.html)
|
||||
* [tasks](http://doc.rust-lang.org/doc/0.9/guide-tasks.html)
|
||||
* [testing](http://doc.rust-lang.org/doc/0.9/guide-testing.html)
|
||||
* [Manual](http://doc.rust-lang.org/doc/0.9/rust.html) ([PDF](http://doc.rust-lang.org/doc/0.9/rust.pdf))
|
||||
* [Standard library](http://doc.rust-lang.org/doc/0.9/std/index.html)
|
||||
* [Extra library](http://doc.rust-lang.org/doc/0.9/extra/index.html)
|
||||
* [Package manager](http://doc.rust-lang.org/doc/0.9/rustpkg.html)
|
||||
# Guides
|
||||
|
||||
**In-development (git master)**
|
||||
[Pointers](guide-pointers.html)
|
||||
[Lifetimes](guide-lifetimes.html)
|
||||
[Containers and Iterators](guide-container.html)
|
||||
[Tasks and Communication](guide-tasks.html)
|
||||
[Foreign Function Interface](guide-ffi.html)
|
||||
[Macros](guide-macros.html)
|
||||
[Packaging](guide-rustpkg.html)
|
||||
[Testing](guide-testing.html)
|
||||
[Conditions](guide-conditions.html)
|
||||
|
||||
* [Tutorial](http://doc.rust-lang.org/doc/master/tutorial.html) ([PDF](http://doc.rust-lang.org/doc/master/tutorial.pdf))
|
||||
* Guides
|
||||
* [borrowed pointers](http://doc.rust-lang.org/doc/master/guide-borrowed-ptr.html)
|
||||
* [conditions](http://doc.rust-lang.org/doc/master/guide-conditions.html)
|
||||
* [containers & iterators](http://doc.rust-lang.org/doc/master/guide-container.html)
|
||||
* [ffi](http://doc.rust-lang.org/doc/master/guide-ffi.html)
|
||||
* [macros](http://doc.rust-lang.org/doc/master/guide-macros.html)
|
||||
* [rustpkg](http://doc.rust-lang.org/doc/master/guide-rustpkg.html)
|
||||
* [tasks](http://doc.rust-lang.org/doc/master/guide-tasks.html)
|
||||
* [testing](http://doc.rust-lang.org/doc/master/guide-testing.html)
|
||||
* [Manual](http://doc.rust-lang.org/doc/master/rust.html) ([PDF](http://doc.rust-lang.org/doc/master/rust.pdf))
|
||||
* [Standard library](http://doc.rust-lang.org/doc/master/std/index.html)
|
||||
* [Extra library](http://doc.rust-lang.org/doc/master/extra/index.html)
|
||||
* [libgreen](http://static.rust-lang.org/doc/master/green/index.html)
|
||||
* [libnative](http://static.rust-lang.org/doc/master/native/index.html)
|
||||
* [Package manager](http://doc.rust-lang.org/doc/master/rustpkg.html)
|
||||
# Libraries
|
||||
|
||||
[std](std/index.html)
|
||||
[extra](index.html)
|
||||
|
||||
# Tooling
|
||||
|
||||
[The rustpkg manual](rustpkg.html)
|
||||
|
||||
# FAQs
|
||||
|
||||
* [Language FAQ][lang-faq]
|
||||
* [Project FAQ][project-faq]
|
||||
* [Usage FAQ][usage-faq]
|
||||
* [Code cheatsheet][cheatsheet] - "How do I do X?"
|
||||
* [HOWTO submit a bug report][bugreport]
|
||||
[Language FAQ](complement-lang-faq.html)
|
||||
[Project FAQ](complement-project-faq.html)
|
||||
[Usage FAQ](complement-usage-faq.html)
|
||||
[Code cheatsheet](complement-cheatsheet.html) - "How do I do X?"
|
||||
[HOWTO submit a bug report](complement-bugreport.html)
|
||||
|
||||
[lang-faq]: complement-lang-faq.html
|
||||
[project-faq]: complement-project-faq.html
|
||||
[usage-faq]: complement-usage-faq.html
|
||||
[cheatsheet]: complement-cheatsheet.html
|
||||
[bugreport]: complement-bugreport.html
|
||||
# External resources
|
||||
|
||||
# Community
|
||||
|
||||
|
||||
> **Note** that to guard against botnet attacks we occasionally turn on moderation, disallowing
|
||||
> unregistered users from joining or talking. You may need to [register](https://wiki.mozilla.org/IRC#Register_your_nickname) your nickname. Sorry for the inconvenience.*
|
||||
|
||||
* IRC
|
||||
* [#rust on irc.mozilla.org][pound-rust] - Main Rust channel - general discussion
|
||||
* [#rust-internals on irc.mozilla.org][pound-rust-internals] - Rust compiler and library development
|
||||
* [#rust-gamedev on irc.mozilla.org][pound-rust-gamedev] - game development in Rust
|
||||
* [#rust-osdev on irc.mozill.org][pound-rust-osdev] - OS development in Rust
|
||||
* [#rust on irc.ozinger.org][pound-rust-korea] - Korean Rust community
|
||||
|
||||
* Mailing list [rust-dev]
|
||||
* Reddit's [r/rust]
|
||||
* User groups
|
||||
* [Rust Bay Area][rust-bay-area]
|
||||
* [Rust Korea][rust-korea]
|
||||
* [Rust Skåne][rust-skane]
|
||||
* [Rust 中文圈][rust-zh] (on Google+)
|
||||
|
||||
[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
|
||||
[pound-rust-internals]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
|
||||
[pound-rust-gamedev]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-gamedev
|
||||
[pound-rust-osdev]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-osdev
|
||||
[pound-rust-korea]: http://chat.mibbit.com/?server=irc.ozinger.org&channel=%23rust
|
||||
[rust-dev]: https://mail.mozilla.org/listinfo/rust-dev
|
||||
[r/rust]: http://reddit.com/r/rust
|
||||
[rust-bay-area]: http://www.meetup.com/Rust-Bay-Area/
|
||||
[rust-korea]: http://rust-kr.org/
|
||||
[rust-skane]: http://www.meetup.com/rust-skane/
|
||||
[rust-zh]: https://plus.google.com/communities/100629002107624231185/
|
||||
|
||||
# Specialized documentation
|
||||
|
||||
[Releases][release-notes] - Links to current and old releases and documentation
|
||||
[Detailed release notes][detailed-release-notes] - Further explanation of language changes
|
||||
[Rust for C++ programmers][rust-for-c] - A cheat sheet
|
||||
[Rusticon][rust-icon] - A glossary of terms commonly used in Rust and Rust tools.
|
||||
[Unit testing][unit-testing] - Writing tests and running them with the built-in test driver
|
||||
[Using rustpkg][rustpkg] - Managing packages
|
||||
[Using rustdoc][rustdoc] - How to extract Markdown and HTML documentation from code
|
||||
[Package documentation](http://docs.octayn.net/) - Documentation for rust packages
|
||||
[Continuous integration][ci] - Test your GitHub-hosted packages with Travis CI
|
||||
[Reading and writing files][doc-rw]
|
||||
[Attributes][doc-attributes] - The role of metadata in Rust code, with descriptions of many applications
|
||||
[Packages, editors, and other tools][tools]
|
||||
[Packaging Terminology][doc-terminology]
|
||||
[Crate Hashes][crate-hashes] - How Rust generates crate filenames, versions symbols, and why
|
||||
[Computer Graphics and Game Development][game-dev] - Libraries and example projects
|
||||
[Présentation du langage Rust](http://lea-linux.org/documentations/Rust) - Detailed documentation in French, with examples
|
||||
[Building for Android][building-android]
|
||||
[Building for iOS][building-ios]
|
||||
|
||||
[release-notes]: https://github.com/mozilla/rust/wiki/Doc-releases
|
||||
[detailed-release-notes]: https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes
|
||||
[rust-for-c]: https://github.com/mozilla/rust/wiki/Rust-for-CXX-programmers
|
||||
[rust-icon]: https://github.com/mozilla/rust/wiki/The-Rusticon
|
||||
[unit-testing]: https://github.com/mozilla/rust/wiki/Doc-unit-testing
|
||||
[rustpkg]: https://github.com/mozilla/rust/wiki/Rustpkg
|
||||
[rustdoc]: https://github.com/mozilla/rust/wiki/Doc-using-rustdoc
|
||||
[ci]: https://github.com/mozilla/rust/wiki/Doc-continuous-integration
|
||||
[doc-rw]: https://github.com/mozilla/rust/wiki/Doc-reading-and-writing-files
|
||||
[doc-attributes]: https://github.com/mozilla/rust/wiki/Doc-attributes
|
||||
[tools]: https://github.com/mozilla/rust/wiki/Doc-packages%2C-editors%2C-and-other-tools
|
||||
[doc-terminology]: https://github.com/mozilla/rust/wiki/Doc-packaging-terminology
|
||||
[crate-hashes]: https://github.com/mozilla/rust/wiki/Doc-crate-hashes
|
||||
[game-dev]: https://github.com/mozilla/rust/wiki/Computer-Graphics-and-Game-Development
|
||||
[building-android]: https://github.com/mozilla/rust/wiki/Doc-building-for-android
|
||||
[building-ios]: https://github.com/mozilla/rust/wiki/Doc-building-for-ios
|
||||
|
||||
Some Rust classics:
|
||||
|
||||
* [Pointers in Rust: A Guide](http://words.steveklabnik.com/pointers-in-rust-a-guide)
|
||||
* [A taste of Rust](https://lwn.net/Articles/547145/)
|
||||
* [An overview of memory management in Rust](http://pcwalton.github.com/blog/2013/03/18/an-overview-of-memory-management-in-rust/)
|
||||
* [Which pointer should I use?](http://pcwalton.github.com/blog/2013/03/09/which-pointer-should-i-use/)
|
||||
* [Lifetimes explained](http://maikklein.github.io/2013/08/27/lifetimes-explained/)
|
||||
* [Little things that matter in language design](http://lwn.net/Articles/553131/)
|
||||
* [Operator overloading in Rust](http://maniagnosis.crsr.net/2013/04/operator-overloading-in-rust.html)
|
||||
* [Embedding Rust in Ruby](http://brson.github.com/2013/03/10/embedding-rust-in-ruby/)
|
||||
* [A first parallel program in Rust](http://blog.leahhanson.us/a-first-parallel-program-in-rust.html)
|
||||
* [FizzBuzz revisited](http://composition.al/blog/2013/03/02/fizzbuzz-revisited/)
|
||||
* [Ownership types in Rust, and whether they're worth it](http://tim.dreamwidth.org/1784423.html)
|
||||
* [Reasoning about the heap in Rust](http://johnbender.us/2013/04/30/reasoning-about-the-heap-in-rust)
|
||||
* [The Option Type](http://nickdesaulniers.github.io/blog/2013/05/07/rust-pattern-matching-and-the-option-type/)
|
||||
* [How I got started hacking rustc](http://cmr.github.io/blog/2013/06/23/how-i-got-started-with-rust/)
|
||||
* [Abstraction penalties, stack allocation, and ownership types](http://robert.ocallahan.org/2007/10/abstraction-penalties-stack-allocation_23.html)
|
||||
* [Présentation de Rust 0.8](http://linuxfr.org/news/presentation-de-rust-0-8) - A very detailed article about Rust 0.8, in French!
|
||||
|
||||
# Presentations
|
||||
|
||||
* [John Clements, 10-minute talk (video)](http://www.youtube.com/watch?v=_KgXy7jnwhY) at SoCal PLS on Rust, Macros, and Hygiene. December 2013.
|
||||
* [Felix's Codemesh 2013 slides](http://pnkfelix.github.io/present-rust-codemesh2013/fklock-rust-codemesh2013.pdf)
|
||||
* Geoffroy Couprie's [Scala.IO 2013 slides](http://dev.unhandledexpression.com/slides/rust-scalaio/)
|
||||
* Steve's presentation at RuPy 2013 "Nobody Knows Rust." [slides](http://steveklabnik.github.io/nobody_knows_rust/#/), video to come soon
|
||||
* [Tim's presentation at OS Bridge 2013](http://opensourcebridge.org/sessions/970) - And [slides](http://opensourcebridge.org/wiki/2013/Rust%3A_A_Friendly_Introduction)
|
||||
* [Niko's presentation at Northeastern](http://smallcultfollowing.com/babysteps/blog/2013/07/18/rust-presentation-at-northeastern/) - Slides only
|
||||
* [An I/O system for Rust](https://air.mozilla.org/intern-presentations-reed/) - Eric Reed's intern presentation on I/O
|
||||
* [Types of Types](https://air.mozilla.org/ben-blum-from-the-research-team-presents-types-of-types-in-rust/) - Ben Blum's intern presentation on 'kinds'
|
||||
* [Default methods in Rust](https://air.mozilla.org/intern-presentation-sullivan/) - Michael Sullivan's intern presentation on default methods
|
||||
* [A work stealing runtime for Rust](https://air.mozilla.org/2013-intern-todd/) - Aaron Todd's intern presentation on the Rust scheduler
|
||||
* [Dave Herman's StrangeLoop 2012 talk](http://www.infoq.com/presentations/Rust)
|
||||
The Rust [IRC channel](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) - #rust on irc.mozilla.org
|
||||
The Rust community on [Reddit](http://reddit.com/r/rust)
|
||||
The Rust [wiki](http://github.com/mozilla/rust/wiki)
|
||||
|
@ -1423,10 +1423,8 @@ intuitive sense: you must wait for a borrowed value to be returned
|
||||
(that is, for the borrowed pointer to go out of scope) before you can
|
||||
make full use of it again.
|
||||
|
||||
For a more in-depth explanation of borrowed pointers, read the
|
||||
[borrowed pointer tutorial][borrowtut].
|
||||
|
||||
[borrowtut]: tutorial-borrowed-ptr.html
|
||||
For a more in-depth explanation of borrowed pointers and lifetimes, read the
|
||||
[lifetimes and borrowed pointer tutorial][lifetimes].
|
||||
|
||||
## Freezing
|
||||
|
||||
@ -3269,7 +3267,8 @@ re-export a bunch of 'officially blessed' crates that get managed with `rustpkg`
|
||||
Now that you know the essentials, check out any of the additional
|
||||
guides on individual topics.
|
||||
|
||||
* [Borrowed pointers][borrow]
|
||||
* [Pointers][pointers]
|
||||
* [Lifetimes][lifetimes]
|
||||
* [Tasks and communication][tasks]
|
||||
* [Macros][macros]
|
||||
* [The foreign function interface][ffi]
|
||||
@ -3279,9 +3278,10 @@ guides on individual topics.
|
||||
* [Documenting Rust code][rustdoc]
|
||||
* [Testing Rust code][testing]
|
||||
|
||||
There is further documentation on the [Main Page](index.html).
|
||||
There is further documentation on the [wiki], however those tend to be even more out of date as this document.
|
||||
|
||||
[borrow]: guide-borrowed-ptr.html
|
||||
[pointers]: guide-pointers.html
|
||||
[lifetimes]: guide-lifetimes.html
|
||||
[tasks]: guide-tasks.html
|
||||
[macros]: guide-macros.html
|
||||
[ffi]: guide-ffi.html
|
||||
@ -3290,5 +3290,6 @@ There is further documentation on the [Main Page](index.html).
|
||||
[rustpkg]: guide-rustpkg.html
|
||||
[testing]: guide-testing.html
|
||||
[rustdoc]: rustdoc.html
|
||||
[wiki]: https://github.com/mozilla/rust/wiki/Docs
|
||||
|
||||
[wiki-packages]: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools
|
||||
|
14
mk/docs.mk
14
mk/docs.mk
@ -19,8 +19,8 @@ HTML_DEPS :=
|
||||
|
||||
BASE_DOC_OPTS := --from=markdown --standalone --toc --number-sections
|
||||
HTML_OPTS = $(BASE_DOC_OPTS) --to=html5 --section-divs --css=rust.css \
|
||||
--include-before-body=doc/version_info.html \
|
||||
--include-in-header=doc/favicon.inc
|
||||
--include-before-body=doc/version_info.html \
|
||||
--include-in-header=doc/favicon.inc
|
||||
TEX_OPTS = $(BASE_DOC_OPTS) --to=latex
|
||||
EPUB_OPTS = $(BASE_DOC_OPTS) --to=epub
|
||||
|
||||
@ -194,8 +194,8 @@ doc/guide-testing.html: $(S)doc/guide-testing.md $(HTML_DEPS)
|
||||
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
|
||||
$(CFG_PANDOC) $(HTML_OPTS) --output=$@
|
||||
|
||||
DOCS += doc/guide-borrowed-ptr.html
|
||||
doc/guide-borrowed-ptr.html: $(S)doc/guide-borrowed-ptr.md $(HTML_DEPS)
|
||||
DOCS += doc/guide-lifetimes.html
|
||||
doc/guide-lifetimes.html: $(S)doc/guide-lifetimes.md $(HTML_DEPS)
|
||||
@$(call E, pandoc: $@)
|
||||
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
|
||||
$(CFG_PANDOC) $(HTML_OPTS) --output=$@
|
||||
@ -218,6 +218,12 @@ doc/guide-rustpkg.html: $(S)doc/guide-rustpkg.md $(HTML_DEPS)
|
||||
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
|
||||
$(CFG_PANDOC) $(HTML_OPTS) --output=$@
|
||||
|
||||
DOCS += doc/guide-pointers.html
|
||||
doc/guide-pointers.html: $(S)doc/guide-pointers.md $(HTML_DEPS)
|
||||
@$(call E, pandoc: $@)
|
||||
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
|
||||
$(CFG_PANDOC) $(HTML_OPTS) --output=$@
|
||||
|
||||
ifeq ($(CFG_PDFLATEX),)
|
||||
$(info cfg: no pdflatex found, omitting doc/rust.pdf)
|
||||
else
|
||||
|
@ -20,8 +20,9 @@ TEST_HOST_CRATES = rustpkg rustc rustdoc syntax
|
||||
TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
|
||||
|
||||
# Markdown files under doc/ that should have their code extracted and run
|
||||
DOC_TEST_NAMES = tutorial guide-ffi guide-macros guide-borrowed-ptr \
|
||||
guide-tasks guide-conditions guide-container rust
|
||||
DOC_TEST_NAMES = tutorial guide-ffi guide-macros guide-lifetimes \
|
||||
guide-tasks guide-conditions guide-container guide-pointers \
|
||||
rust
|
||||
|
||||
######################################################################
|
||||
# Environment configuration
|
||||
|
Loading…
Reference in New Issue
Block a user