rust/src/doc/trpl
2015-10-08 07:15:39 +02:00
..
advanced-linking.md libcxxabi is no longer necessary for libunwind 2015-09-30 07:42:34 +01:00
associated-constants.md
associated-types.md usize -> u32 to match previous example 2015-06-12 15:59:39 -04:00
attributes.md
benchmark-tests.md
bibliography.md Update bibliography.md 2015-10-04 15:55:19 -07:00
borrow-and-asref.md
box-syntax-and-patterns.md
casting-between-types.md
choosing-your-guarantees.md Fix "more more" typo 2015-09-19 17:19:29 -07:00
closures.md trpl: Refactor returning closures section 2015-09-25 00:17:54 +05:30
comments.md book: introduce //! doc comment in comments section 2015-07-06 14:55:06 +08:00
compiler-plugins.md Use https URLs to refer to rust-lang.org where appropriate. 2015-08-09 14:28:46 -07:00
concurrency.md docs: anchors fixes 2015-10-05 19:25:54 +03:00
conditional-compilation.md docs: anchors fixes 2015-10-05 19:25:54 +03:00
const-and-static.md Rollup merge of #26144 - steveklabnik:static_doc_fix, r=alexcrichton 2015-06-09 17:24:45 -04:00
crates-and-modules.md Complex import example needs blank lines 2015-10-06 00:11:18 -05:00
deref-coercions.md Take method invocation semantics out of chapter on deref coercion. 2015-09-03 21:17:59 +02:00
dining-philosophers.md docs: anchors fixes 2015-10-05 19:25:54 +03:00
documentation.md Add in some <hr>s for emphasis 2015-10-02 18:54:15 -04:00
drop.md
effective-rust.md
enums.md Mention that enum constructors are functions 2015-06-09 16:12:45 -04:00
error-handling.md docs: anchors fixes 2015-10-05 19:25:54 +03:00
ffi.md Be explicit about using crates.io's libc crate 2015-08-28 11:43:23 -04:00
functions.md Add note about backtraces to TRPL 2015-08-18 14:22:18 -04:00
generics.md Small formatting/syntax tweaks 2015-09-05 19:54:52 -07:00
getting-started.md
glossary.md docs: anchors fixes 2015-10-05 19:25:54 +03:00
guessing-game.md Elaborate on the io prelude in the book 2015-09-30 13:39:59 -04:00
hello-cargo.md required -> used; you -> we 2015-08-03 21:37:15 +01:00
hello-world.md Add missing dot 2015-10-03 20:21:39 +02:00
if-let.md
if.md
inline-assembly.md doc: Add a link to LLVM's new inline assembly docs 2015-07-13 10:08:09 -07:00
installing-rust.md Change OSX version req wording to match Linux. 2015-09-16 18:56:56 -04:00
intrinsics.md Show appropriate feature flags in docs 2015-07-27 12:28:13 -04:00
iterators.md remove a sentence #28701 2015-09-28 10:46:50 -05:00
lang-items.md Remove morestack support 2015-08-10 16:35:44 -07:00
learn-rust.md
lifetimes.md Wrap words at 80 characters 2015-10-06 10:39:37 -04:00
loops.md Fix typo 2015-08-31 06:44:27 +02:00
macros.md Fix link to hygienic macros on Wikipedia 2015-09-08 14:06:35 +02:00
match.md
method-syntax.md Capitalize circle reference 2015-09-03 20:51:08 -07:00
mutability.md Rollup merge of #28283 - rutsky:patch-3, r=steveklabnik 2015-09-09 18:36:11 +05:30
nightly-rust.md Use https URLs to refer to rust-lang.org where appropriate. 2015-08-09 14:28:46 -07:00
no-stdlib.md Update no_std docs 2015-09-30 11:46:33 -04:00
operators-and-overloading.md Using operator traits in generic structs 2015-07-30 21:49:13 +02:00
ownership.md Replace multiple trailing newlines with a single trailing newline 2015-10-06 13:06:39 -04:00
patterns.md fix capitalization inside sentense 2015-09-09 12:54:31 +03:00
primitive-types.md Call out slicing syntax more explicitly 2015-09-30 13:21:04 -04:00
raw-pointers.md Exise 'unsafe pointer' in favor of 'raw pointer' 2015-06-09 16:49:24 -04:00
README.md trpl: Rename 'academic research' to 'bibliography'. Add some new links. 2015-09-04 09:37:15 -07:00
references-and-borrowing.md Clean newlines 2015-10-06 11:14:11 -04:00
release-channels.md Add travis config to TRPL: release channels 2015-07-20 20:14:23 -04:00
rust-inside-other-languages.md Docs: Removes duplicate output from FFI example 2015-10-04 10:44:00 +01:00
slice-patterns.md
strings.md TRPL: minor correction on how chars().nth() work 2015-08-09 00:56:38 +02:00
structs.md Add an example of constructing a unit-like struct. 2015-09-26 11:59:02 -07:00
SUMMARY.md trpl: Rename 'academic research' to 'bibliography'. Add some new links. 2015-09-04 09:37:15 -07:00
syntax-and-semantics.md
testing.md Cross-reference doc chapter from testing chapter 2015-09-30 13:31:17 -04:00
the-stack-and-the-heap.md Rollup merge of #28772 - tshepang:improve-paragraph, r=steveklabnik 2015-09-30 18:20:04 -04:00
trait-objects.md Add object safety to TRPL 2015-08-18 11:27:02 -04:00
traits.md trpl: mention deriving in traits section 2015-10-08 07:15:39 +02:00
type-aliases.md
ufcs.md
unsafe.md Klabnik nit-picks ;) 2015-07-21 22:09:29 +02:00
unsized-types.md
variable-bindings.md Improve "Variable bindings" chapter 2015-09-30 02:42:52 +02:00
vectors.md Mention that you can only index with usize 2015-09-30 13:46:58 -04:00

% The Rust Programming Language

Welcome! This book will teach you about the Rust Programming Language. Rust is a systems programming language focused on three goals: safety, speed, and concurrency. It maintains these goals without having a garbage collector, making it a useful language for a number of use cases other languages arent good at: embedding in other languages, programs with specific space and time requirements, and writing low-level code, like device drivers and operating systems. It improves on current languages targeting this space by having a number of compile-time safety checks that produce no runtime overhead, while eliminating all data races. Rust also aims to achieve zero-cost abstractions even though some of these abstractions feel like those of a high-level language. Even then, Rust still allows precise control like a low-level language would.

“The Rust Programming Language” is split into eight sections. This introduction is the first. After this:

  • Getting started - Set up your computer for Rust development.
  • Learn Rust - Learn Rust programming through small projects.
  • Effective Rust - Higher-level concepts for writing excellent Rust code.
  • Syntax and Semantics - Each bit of Rust, broken down into small chunks.
  • Nightly Rust - Cutting-edge features that arent in stable builds yet.
  • Glossary - A reference of terms used in the book.
  • Bibliography - Background on Rust's influences, papers about Rust.

After reading this introduction, youll want to dive into either Learn Rust or Syntax and Semantics, depending on your preference: Learn Rust if you want to dive in with a project, or Syntax and Semantics if you prefer to start small, and learn a single concept thoroughly before moving onto the next. Copious cross-linking connects these parts together.

Contributing

The source files from which this book is generated can be found on Github: github.com/rust-lang/rust/tree/master/src/doc/trpl

A brief introduction to Rust

Is Rust a language you might be interested in? Lets examine a few small code samples to show off a few of its strengths.

The main concept that makes Rust unique is called ownership. Consider this small example:

fn main() {
    let mut x = vec!["Hello", "world"];
}

This program makes a variable binding named x. The value of this binding is a Vec<T>, a vector, that we create through a macro defined in the standard library. This macro is called vec, and we invoke macros with a !. This follows a general principle of Rust: make things explicit. Macros can do significantly more complicated things than function calls, and so theyre visually distinct. The ! also helps with parsing, making tooling easier to write, which is also important.

We used mut to make x mutable: bindings are immutable by default in Rust. Well be mutating this vector later in the example.

Its also worth noting that we didnt need a type annotation here: while Rust is statically typed, we didnt need to explicitly annotate the type. Rust has type inference to balance out the power of static typing with the verbosity of annotating types.

Rust prefers stack allocation to heap allocation: x is placed directly on the stack. However, the Vec<T> type allocates space for the elements of the vector on the heap. If youre not familiar with this distinction, you can ignore it for now, or check out The Stack and the Heap. As a systems programming language, Rust gives you the ability to control how your memory is allocated, but when were getting started, its less of a big deal.

Earlier, we mentioned that ownership is the key new concept in Rust. In Rust parlance, x is said to own the vector. This means that when x goes out of scope, the vectors memory will be de-allocated. This is done deterministically by the Rust compiler, rather than through a mechanism such as a garbage collector. In other words, in Rust, you dont call functions like malloc and free yourself: the compiler statically determines when you need to allocate or deallocate memory, and inserts those calls itself. To err is to be human, but compilers never forget.

Lets add another line to our example:

fn main() {
    let mut x = vec!["Hello", "world"];

    let y = &x[0];
}

Weve introduced another binding, y. In this case, y is a reference to the first element of the vector. Rusts references are similar to pointers in other languages, but with additional compile-time safety checks. References interact with the ownership system by borrowing what they point to, rather than owning it. The difference is, when the reference goes out of scope, it will not deallocate the underlying memory. If it did, wed de-allocate twice, which is bad!

Lets add a third line. It looks innocent enough, but causes a compiler error:

fn main() {
    let mut x = vec!["Hello", "world"];

    let y = &x[0];

    x.push("foo");
}

push is a method on vectors that appends another element to the end of the vector. When we try to compile this program, we get an error:

error: cannot borrow `x` as mutable because it is also borrowed as immutable
    x.push("foo");
    ^
note: previous borrow of `x` occurs here; the immutable borrow prevents
subsequent moves or mutable borrows of `x` until the borrow ends
    let y = &x[0];
             ^
note: previous borrow ends here
fn main() {

}
^

Whew! The Rust compiler gives quite detailed errors at times, and this is one of those times. As the error explains, while we made our binding mutable, we still cannot call push. This is because we already have a reference to an element of the vector, y. Mutating something while another reference exists is dangerous, because we may invalidate the reference. In this specific case, when we create the vector, we may have only allocated space for two elements. Adding a third would mean allocating a new chunk of memory for all those elements, copying the old values over, and updating the internal pointer to that memory. That all works just fine. The problem is that y wouldnt get updated, and so wed have a dangling pointer. Thats bad. Any use of y would be an error in this case, and so the compiler has caught this for us.

So how do we solve this problem? There are two approaches we can take. The first is making a copy rather than using a reference:

fn main() {
    let mut x = vec!["Hello", "world"];

    let y = x[0].clone();

    x.push("foo");
}

Rust has move semantics by default, so if we want to make a copy of some data, we call the clone() method. In this example, y is no longer a reference to the vector stored in x, but a copy of its first element, "Hello". Now that we dont have a reference, our push() works just fine.

If we truly want a reference, we need the other option: ensure that our reference goes out of scope before we try to do the mutation. That looks like this:

fn main() {
    let mut x = vec!["Hello", "world"];

    {
        let y = &x[0];
    }

    x.push("foo");
}

We created an inner scope with an additional set of curly braces. y will go out of scope before we call push(), and so were all good.

This concept of ownership isnt just good for preventing dangling pointers, but an entire set of related problems, like iterator invalidation, concurrency, and more.