`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
`IterBytes`, `Rand`, `Zero`, and `ToStr`.
- # Modules and crates
+ # Crates and the module system
- The Rust namespace is arranged in a hierarchy of modules. Each source
- (.rs) file represents a single module and may in turn contain
- additional modules.
+ Rust's module system is very powerful, but because of that also somewhat complex.
+ Nevertheless, this section will try to explain every important aspect of it.
+
+ ## Crates
+
+ In order to speak about the module system, we first need to define the medium it exists in:
+
+ Let's say you've written a program or a library, compiled it, and got the resulting binary.
+ In Rust, the content of all source code that the compiler directly had to compile in order to end up with
+ that binary is collectively called a 'crate'.
+
+ For example, for a simple hello world program your crate only consists of this code:
+
+ ~~~~
+ // main.rs
+ fn main() {
+ println("Hello world!");
+ }
+ ~~~~
+
+ A crate is also the unit of independent compilation in Rust: `rustc` always compiles a single crate at a time,
+ from which it produces either a library or an executable.
+
+ Note that merely using an already compiled library in your code does not make it part of your crate.
+
+ ## The module hierarchy
+
+ For every crate, all the code in it is arranged in a hierarchy of modules starting with a single
+ root module. That root module is called the 'crate root'.
+
+ All modules in a crate below the crate root are declared with the `mod` keyword:
~~~~
+ // This is the crate root
+
mod farm {
- pub fn chicken() -> &str { "cluck cluck" }
- pub fn cow() -> &str { "mooo" }
+ // This is the body of module 'farm' declared in the crate root.
+
+ fn chicken() { println("cluck cluck"); }
+ fn cow() { println("mooo"); }
+
+ mod barn {
+ // Body of module 'barn'
+
+ fn hay() { println("..."); }
+ }
}
fn main() {
- println(farm::chicken());
+ println("Hello farm!");
}
~~~~
- The contents of modules can be imported into the current scope
- with the `use` keyword, optionally giving it an alias. `use`
- may appear at the beginning of crates, `mod`s, `fn`s, and other
- blocks.
+ As you can see, your module hierarchy is now three modules deep: There is the crate root, which contains your `main()`
+ function, and the module `farm`. The module `farm` also contains two functions and a third module `barn`,
+ which contains a function `hay`.
- ~~~
- # mod farm { pub fn chicken() { } }
- # fn main() {
- // Bring `chicken` into scope
- use farm::chicken;
+ (In case you already stumbled over `extern mod`: It isn't directly related to a bare `mod`, we'll get to it later. )
+
+ ## Paths and visibility
- fn chicken_farmer() {
- // The same, but name it `my_chicken`
- use my_chicken = farm::chicken;
- ...
- # my_chicken();
+ We've now defined a nice module hierarchy. But how do we access the items in it from our `main` function?
+ One way to do it is to simply fully qualifying it:
+
+ ~~~~ {.xfail-test}
+ mod farm {
+ fn chicken() { println("cluck cluck"); }
+ // ...
}
- # chicken();
- # }
- ~~~
- These farm animal functions have a new keyword, `pub`, attached to
- them. The `pub` keyword modifies an item's visibility, making it
- visible outside its containing module. An expression with `::`, like
- `farm::chicken`, can name an item outside of its containing
- module. Items, such as those declared with `fn`, `struct`, `enum`,
- `type`, or `static`, are module-private by default.
+ fn main() {
+ println("Hello chicken!");
+
+ ::farm::chicken(); // Won't compile yet, see further down
+ }
+ ~~~~
+
+ The `::farm::chicken` construct is what we call a 'path'.
+
+ Because it's starting with a `::`, it's also a 'global path',
+ which qualifies an item by its full path in the module hierarchy
+ relative to the crate root.
+
+ If the path were to start with a regular identifier, like `farm::chicken`, it would be
+ a 'local path' instead. We'll get to them later.
+
+ Now, if you actually tried to compile this code example, you'll notice
+ that you get a `unresolved name: 'farm::chicken'` error. That's because per default,
+ items (`fn`, `struct`, `static`, `mod`, ...) are only visible inside the module
+ they are defined in.
+
+ To make them visible outside their containing modules, you need to mark them _public_ with `pub`:
+
+ ~~~~
+ mod farm {
+ pub fn chicken() { println("cluck cluck"); }
+ pub fn cow() { println("mooo"); }
+ // ...
+ }
+
+ fn main() {
+ println("Hello chicken!");
+ ::farm::chicken(); // This compiles now
+ }
+ ~~~~
Visibility restrictions in Rust exist only at module boundaries. This
is quite different from most object-oriented languages that also
enforce restrictions on objects themselves. That's not to say that
Rust doesn't support encapsulation: both struct fields and methods can
be private. But this encapsulation is at the module level, not the
- struct level. Note that fields and methods are _public_ by default.
+ struct level.
+
+ For convenience, fields are _public_ by default, and can be made _private_ with the `priv` keyword:
~~~
- pub mod farm {
+ mod farm {
# pub type Chicken = int;
- # type Cow = int;
# struct Human(int);
# impl Human { fn rest(&self) { } }
- # pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }
+ # pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], farmer: Human(0) } }
pub struct Farm {
priv chickens: ~[Chicken],
- priv cows: ~[Cow],
farmer: Human
}
impl Farm {
fn feed_chickens(&self) { ... }
- fn feed_cows(&self) { ... }
pub fn add_chicken(&self, c: Chicken) { ... }
}
pub fn feed_animals(farm: &Farm) {
farm.feed_chickens();
- farm.feed_cows();
}
}
fn main() {
- let f = make_me_a_farm();
- f.add_chicken(make_me_a_chicken());
- farm::feed_animals(&f);
- f.farmer.rest();
+ let f = make_me_a_farm();
+ f.add_chicken(make_me_a_chicken());
+ farm::feed_animals(&f);
+ f.farmer.rest();
+
+ // This wouldn't compile because both are private:
+ // f.feed_chickens();
+ // let chicken_counter = f.chickens.len();
}
# fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() }
# fn make_me_a_chicken() -> farm::Chicken { 0 }
~~~
- ## Crates
+ > ***Note:*** Visibility rules are currently buggy and not fully defined, you might have to add or remove `pub` along a path until it works.
- The unit of independent compilation in Rust is the crate: rustc
- compiles a single crate at a time, from which it produces either a
- library or an executable.
-
- When compiling a single `.rs` source file, the file acts as the whole crate.
- You can compile it with the `--lib` compiler switch to create a shared
- library, or without, provided that your file contains a `fn main`
- somewhere, to create an executable.
-
- Larger crates typically span multiple files and are, by convention,
- compiled from a source file with the `.rc` extension, called a *crate file*.
- The crate file extension distinguishes source files that represent
- crates from those that do not, but otherwise source files and crate files are identical.
-
- A typical crate file declares attributes associated with the crate that
- may affect how the compiler processes the source.
- Crate attributes specify metadata used for locating and linking crates,
- the type of crate (library or executable),
- and control warning and error behavior,
- among other things.
- Crate files additionally declare the external crates they depend on
- as well as any modules loaded from other files.
-
- ~~~~ { .xfail-test }
- // Crate linkage metadata
- #[link(name = "farm", vers = "2.5", author = "mjh")];
+ ## Files and modules
- // Make a library ("bin" is the default)
- #[crate_type = "lib"];
+ One important aspect about Rusts module system is that source files are not important:
+ You define a module hierarchy, populate it with all your definitions, define visibility,
+ maybe put in a `fn main()`, and that's it: No need to think about source files.
- // Turn on a warning
- #[warn(non_camel_case_types)]
+ The only file that's relevant is the one that contains the body of your crate root,
+ and it's only relevant because you have to pass that file to `rustc` to compile your crate.
- // Link to the standard library
- extern mod std;
+ And in principle, that's all you need: You can write any Rust program as one giant source file that contains your
+ crate root and everything below it in `mod ... { ... }` declarations.
+
+ However, in practice you usually want to split you code up into multiple source files to make it more manageable.
+ In order to do that, Rust allows you to move the body of any module into it's own source file, which works like this:
- // Load some modules from other files
- mod cow;
- mod chicken;
- mod horse;
+ If you declare a module without its body, like `mod foo;`, the compiler will look for the
+ files `foo.rs` and `foo/mod.rs`. If it finds either, it uses the content of that file as the body of the module.
+ If it finds both, that's a compile error.
+
+ So, if we want to move the content of `mod farm` into it's own file, it would look like this:
+
+ ~~~~ {.ignore}
+ // main.rs - contains body of the crate root
+ mod farm; // Compiler will look for 'farm.rs' and 'farm/mod.rs'
fn main() {
- ...
+ println("Hello farm!");
+ ::farm::cow();
}
~~~~
- Compiling this file will cause `rustc` to look for files named
- `cow.rs`, `chicken.rs`, and `horse.rs` in the same directory as the
- `.rc` file, compile them all together, and, based on the presence of
- the `crate_type = "lib"` attribute, output a shared library or an
- executable. (If the line `#[crate_type = "lib"];` was omitted,
- `rustc` would create an executable.)
+ ~~~~
+ // farm.rs - contains body of module 'farm' in the crate root
+ pub fn chicken() { println("cluck cluck"); }
+ pub fn cow() { println("mooo"); }
- The `#[link(...)]` attribute provides meta information about the
- module, which other crates can use to load the right module. More
- about that later.
+ pub mod barn {
+ pub fn hay() { println("..."); }
+ }
+ # fn main() { }
+ ~~~~
- To have a nested directory structure for your source files, you can
- nest mods:
+ So, in short `mod foo;` is just syntactic sugar for `mod foo { /* include content of foo.rs or foo/mod.rs here */ }`.
- ~~~~ {.ignore}
- mod poultry {
- mod chicken;
- mod turkey;
+ This also means that having two or more identical `mod foo;` somewhere
+ in your crate hierarchy is generally a bad idea,
+ just like copy-and-paste-ing a module into two or more places is one.
+ Both will result in duplicate and mutually incompatible definitions.
+
+ The directory the compiler looks in for those two files is determined by starting with
+ the same directory as the source file that contains the `mod foo;` declaration, and concatenating to that a
+ path equivalent to the relative path of all nested `mod { ... }` declarations the `mod foo;` is contained in, if any.
+
+ For example, given a file with this module body:
+
+ ~~~ {.ignore}
+ // src/main.rs
+ mod plants;
+ mod fungi;
+ mod animals {
+ mod fish;
+ mod mammals {
+ mod humans;
+ }
+ }
+ ~~~
+
+ The compiler would then try all these files:
+
+ ~~~ {.notrust}
+ src/plants.rs
+ src/plants/mod.rs
+
+ src/fungi.rs
+ src/fungi/mod.rs
+
+ src/animals/fish.rs
+ src/animals/fish/mod.rs
+
+ src/animals/mammals/humans.rs
+ src/animals/mammals/humans/mod.rs
+ ~~~
+
+ These rules per default result in any directory structure mirroring
+ the crates's module hierarchy, and allow you to have both small modules that only need
+ to consist of one source file, and big modules that group the source files of submodules together.
+
+ If you need to circumvent those defaults, you can also overwrite the path a `mod foo;` would take:
+
+ ~~~ {.ignore}
+ #[path="../../area51/classified.rs"]
+ mod alien;
+ ~~~
+
+ ## Importing names into the local scope
+
+ Always referring to definitions in other modules with their global
+ path gets old really fast, so Rust has a way to import
+ them into the local scope of your module: `use`-statements.
+
+ They work like this: At the beginning of any module body, `fn` body, or any other block
+ you can write a list of `use`-statements, consisting of the keyword `use` and a __global path__ to an item
+ without the `::` prefix. For example, this imports `cow` into the local scope:
+
+ ~~~
+ use farm::cow;
+ # mod farm { pub fn cow() { println("I'm a hidden ninja cow!") } }
+ # fn main() { cow() }
+ ~~~
+
+ The path you give to `use` is per default global, meaning relative to the crate root,
+ no matter how deep the module hierarchy is, or whether the module body it's written in
+ is contained in its own file (remember: files are irrelevant).
+
+ This is different to other languages, where you often only find a single import construct that combines the semantic
+ of `mod foo;` and `use`-statements, and which tend to work relative to the source file or use an absolute file path
+ - Rubys `require` or C/C++'s `#include` come to mind.
+
+ However, it's also possible to import things relative to the module of the `use`-statement:
+ Adding a `super::` in front of the path will start in the parent module,
+ while adding a `self::` prefix will start in the current module:
+
+ ~~~
+ # mod workaround {
+ # pub fn some_parent_item(){ println("...") }
+ # mod foo {
+ use super::some_parent_item;
+ use self::some_child_module::some_item;
+ # pub fn bar() { some_parent_item(); some_item() }
+ # pub mod some_child_module { pub fn some_item() {} }
+ # }
+ # }
+ ~~~
+
+ Again - relative to the module, not to the file.
+
+ Imports are also shadowed by local definitions:
+ For each name you mention in a module/block, `rust`
+ will first look at all items that are defined locally,
+ and only if that results in no match look at items you brought in
+ scope with corresponding `use` statements.
+
+ ~~~ {.ignore}
+ # // XXX: Allow unused import in doc test
+ use farm::cow;
+ // ...
+ # mod farm { pub fn cow() { println("Hidden ninja cow is hidden.") } }
+ fn cow() { println("Mooo!") }
+
+ fn main() {
+ cow() // resolves to the locally defined cow() function
}
+ ~~~
+
+ To make this behavior more obvious, the rule has been made that `use`-statement always need to be written
+ before any declaration, like in the example above. This is a purely artificial rule introduced
+ because people always assumed they shadowed each other based on order, despite the fact that all items in rust are
+ mutually recursive, order independent definitions.
+
+ One odd consequence of that rule is that `use` statements also go in front of any `mod` declaration,
+ even if they refer to things inside them:
+
+ ~~~
+ use farm::cow;
+ mod farm {
+ pub fn cow() { println("Moooooo?") }
+ }
+
+ fn main() { cow() }
+ ~~~
+
+ This is what our `farm` example looks like with `use` statements:
+
~~~~
+ use farm::chicken;
+ use farm::cow;
+ use farm::barn;
- The compiler will now look for `poultry/chicken.rs` and
- `poultry/turkey.rs`, and export their content in `poultry::chicken`
- and `poultry::turkey`. You can also provide a `poultry.rs` to add
- content to the `poultry` module itself.
+ mod farm {
+ pub fn chicken() { println("cluck cluck"); }
+ pub fn cow() { println("mooo"); }
- ## Using other crates
+ pub mod barn {
+ pub fn hay() { println("..."); }
+ }
+ }
- The `extern mod` directive lets you use a crate (once it's been
- compiled into a library) from inside another crate. `extern mod` can
- appear at the top of a crate file or at the top of modules. It will
- cause the compiler to look in the library search path (which you can
- extend with the `-L` switch) for a compiled Rust library with the
- right name, then add a module with that crate's name into the local
- scope.
+ fn main() {
+ println("Hello farm!");
- For example, `extern mod std` links the [standard library].
+ // Can now refer to those names directly:
+ chicken();
+ cow();
+ barn::hay();
+ }
+ ~~~~
- [standard library]: std/index.html
+ And here an example with multiple files:
+ ~~~{.ignore}
+ // a.rs - crate root
+ use b::foo;
+ mod b;
+ fn main() { foo(); }
+ ~~~
+ ~~~{.ignore}
+ // b.rs
+ use b::c::bar;
+ pub mod c;
+ pub fn foo() { bar(); }
+ ~~~
+ ~~~
+ // c.rs
+ pub fn bar() { println("Baz!"); }
+ ~~~
- When a comma-separated list of name/value pairs appears after `extern
- mod`, the compiler front-end matches these pairs against the
- attributes provided in the `link` attribute of the crate file. The
- front-end will only select this crate for use if the actual pairs
- match the declared attributes. You can provide a `name` value to
- override the name used to search for the crate.
+ There also exist two short forms for importing multiple names at once:
- Our example crate declared this set of `link` attributes:
+ 1. Explicit mention multiple names as the last element of an `use` path:
+ ~~~
+ use farm::{chicken, cow};
+ # mod farm {
+ # pub fn cow() { println("Did I already mention how hidden and ninja I am?") }
+ # pub fn chicken() { println("I'm Bat-chicken, guardian of the hidden tutorial code.") }
+ # }
+ # fn main() { cow(); chicken() }
+ ~~~
+
+ 2. Import everything in a module with a wildcard:
+ ~~~
+ use farm::*;
+ # mod farm {
+ # pub fn cow() { println("Bat-chicken? What a stupid name!") }
+ # pub fn chicken() { println("Says the 'hidden ninja' cow.") }
+ # }
+ # fn main() { cow(); chicken() }
+ ~~~
+
+ However, that's not all. You can also rename an item while you're bringing it into scope:
+
+ ~~~
+ use egg_layer = farm::chicken;
+ # mod farm { pub fn chicken() { println("Laying eggs is fun!") } }
+ // ...
+
+ fn main() {
+ egg_layer();
+ }
+ ~~~
+
+ In general, `use` creates an local alias:
+ An alternate path and a possibly different name to access the same item,
+ whiteout touching the original, and with both being interchangeable.
+
+ ## Reexporting names
+
+ It is also possible to reexport items to be accessible under your module.
+
+ For that, you write `pub use`:
+
+ ~~~
+ mod farm {
+ pub use self::barn::hay;
+
+ pub fn chicken() { println("cluck cluck"); }
+ pub fn cow() { println("mooo"); }
+
+ mod barn {
+ pub fn hay() { println("..."); }
+ }
+ }
+
+ fn main() {
+ farm::chicken();
+ farm::cow();
+ farm::hay();
+ }
+ ~~~
+
+ Just like in normal `use` statements, the exported names
+ merely represent an alias to the same thing and can also be renamed.
+
+ The above example also demonstrate what you can use `pub use` for:
+ The nested `barn` module is private, but the `pub use` allows users
+ of the module `farm` to access a function from `barn` without needing
+ to know that `barn` exists.
+
+ In other words, you can use them to decouple an public api from their internal implementation.
+
+ ## Using libraries
+
+ So far we've only talked about how to define and structure your own crate.
+
+ However, most code out there will want to use preexisting libraries,
+ as there really is no reason to start from scratch each time you start a new project.
+
+ In Rust terminology, we need a way to refer to other crates.
+
+ For that, Rust offers you the `extern mod` declaration:
+
+ ~~~
+ extern mod extra;
+ // extra ships with Rust, you'll find more details further down.
+
+ fn main() {
+ // The rational number '1/2':
+ let one_half = ::extra::rational::Ratio::new(1, 2);
+ }
+ ~~~
+
+ Despite its name, `extern mod` is a distinct construct from regular `mod` declarations:
+ A statement of the form `extern mod foo;` will cause `rustc` to search for the crate `foo`,
+ and if it finds a matching binary it lets you use it from inside your crate.
+
+ The effect it has on your module hierarchy mirrors aspects of both `mod` and `use`:
+
+ - Like `mod`, it causes `rustc` to actually emit code:
+ The linkage information the binary needs to use the library `foo`.
+
+ - But like `use`, all `extern mod` statements that refer to the same library are interchangeable,
+ as each one really just presents an alias to an external module (the crate root of the library your linking against).
+
+ Remember how `use`-statements have to go before local declarations because the latter shadows the former?
+ Well, `extern mod` statements also have their own rules in that regard:
+ Both `use` and local declarations can shadow them, so the rule is that `extern mod` has to go in front
+ of both `use` and local declarations.
+
+ Which can result in something like this:
+
+ ~~~
+ extern mod extra;
+
+ use farm::dog;
+ use extra::rational::Ratio;
+
+ mod farm {
+ pub fn dog() { println("woof"); }
+ }
+
+ fn main() {
+ farm::dog();
+ let a_third = Ratio::new(1, 3);
+ }
+ ~~~
+
+ It's a bit weird, but it's the result of shadowing rules that have been set that way because
+ they model most closely what people expect to shadow.
+
+ ## Package ids
+
+ If you use `extern mod`, per default `rustc` will look for libraries in the the library search path (which you can
+ extend with the `-L` switch).
+
+ However, Rust also ships with rustpkg, a package manager that is able to automatically download and build
+ libraries if you use it for building your crate. How it works is explained [here][rustpkg],
+ but for this tutorial it's only important to know that you can optionally annotate an
+ `extern mod` statement with an package id that rustpkg can use to identify it:
+
+ ~~~ {.ignore}
+ extern mod rust = "github.com/mozilla/rust"; // pretend Rust is an simple library
+ ~~~
+
+ [rustpkg]: rustpkg.html
+
+ ## Crate metadata and settings
+
+ For every crate you can define a number of metadata items, such as link name, version or author.
+ You can also toggle settings that have crate-global consequences. Both mechanism
+ work by providing attributes in the crate root.
+
+ For example, Rust uniquely identifies crates by their link metadate, which includes
+ the link name and the version. It also hashes the filename and the symbols in a binary
+ based on the link metadata, allowing you to use two different versions of the same library in a crate
+ without conflict.
+
+ Therefor, if you plan to compile your crate as a library, you should annotate it with that information:
~~~~
- #[link(name = "farm", vers = "2.5", author = "mjh")];
+ // lib.rs
+
+ # #[crate_type = "lib"];
+ // Crate linkage metadata
+ #[link(name = "farm", vers = "2.5")];
+
+ // ...
+ # pub fn farm() {}
~~~~
- Which you can then link with any (or all) of the following:
+ You can also in turn require in a `extern mod` statement that certain link metadata items match some criteria.
+ For that, Rust currently parses a comma-separated list of name/value pairs that appear after
+ it, and ensures that they match the attributes provided in the `link` attribute of a crate file.
+ This enables you to, eg, pick a a crate based on it's version number, or to link an library under an
+ different name. For example, this two mod statements would both accept and select the crate define above:
~~~~ {.xfail-test}
- extern mod farm;
- extern mod my_farm (name = "farm", vers = "2.5");
- extern mod my_auxiliary_farm (name = "farm", author = "mjh");
+ extern mod farm(vers = "2.5");
+ extern mod my_farm(name = "farm", vers = "2.5");
+ ~~~~
+
+ Other crate settings and metadata include things like enabling/disabling certain errors or warnings,
+ or setting the crate type (library or executable) explicitly:
+
~~~~
+ // lib.rs
+ // ...
- If any of the requested metadata do not match, then the crate
- will not be compiled successfully.
+ // This crate is a library ("bin" is the default)
+ #[crate_type = "lib"];
+
+ // Turn on a warning
+ #[warn(non_camel_case_types)]
+ # pub fn farm() {}
+ ~~~~
+
+ If you're compiling your crate with `rustpkg`,
+ link annotations will not be necessary, because they get
+ inferred by `rustpkg` based on the Package id and naming conventions.
+
+
+ > ***Note:*** The rules regarding link metadata, both as attributes and on `extern mod`,
+ as well as their interaction with `rustpkg`
+ are currently not clearly defined and will likely change in the future.
## A minimal example
- Now for something that you can actually compile yourself, we have
- these two files:
+ Now for something that you can actually compile yourself.
+
+ We define two crates, and use one of them as a library in the other.
~~~~
// world.rs
- #[link(name = "world", vers = "1.0")];
- pub fn explore() -> &str { "world" }
+ #[link(name = "world", vers = "0.42")];
+ pub fn explore() -> &'static str { "world" }
~~~~
~~~~ {.xfail-test}
// main.rs
extern mod world;
- fn main() { println(~"hello " + world::explore()); }
+ fn main() { println("hello " + world::explore()); }
~~~~
Now compile and run like this (adjust to your platform if necessary):
~~~~ {.notrust}
- > rustc --lib world.rs # compiles libworld-94839cbfe144198-1.0.so
+ > rustc --lib world.rs # compiles libworld-<HASH>-0.42.so
> rustc main.rs -L . # compiles main
> ./main
"hello world"
~~~~
- Notice that the library produced contains the version in the filename
- as well as an inscrutable string of alphanumerics. These are both
- part of Rust's library versioning scheme. The alphanumerics are
- a hash representing the crate metadata.
+ Notice that the library produced contains the version in the file name
+ as well as an inscrutable string of alphanumerics. As explained in the previous paragraph,
+ these are both part of Rust's library versioning scheme. The alphanumerics are
+ a hash representing the crates link metadata.
+
+ ## The standard library and the prelude
+
+ While reading the examples in this tutorial, you might have asked yourself where all
+ those magical predefined items like `println()` are coming from.
+
+ The truth is, there's nothing magical about them: They are all defined normally
+ in the `std` library, which is a crate that ships with Rust.
+
+ The only magical thing that happens is that `rustc` automatically inserts this line into your crate root:
+
+ ~~~ {.ignore}
+ extern mod std;
+ ~~~
+
+ As well as this line into every module body:
+
+ ~~~ {.ignore}
+ use std::prelude::*;
+ ~~~
+
+ The role of the `prelude` module is to re-exports common definitions from `std`.
+
+ This allows you to use common types and functions like `Option<T>` or `println`
+ without needing to import them. And if you need something from `std` that's not in the prelude,
+ you just have to import it with an `use` statement.
+
+ For example, it re-exports `println` which is defined in `std::io::println`:
+
+ ~~~
+ use puts = std::io::println;
+
+ fn main() {
+ println("println is imported per default.");
+ puts("Doesn't hinder you from importing it under an different name yourself.");
+ ::std::io::println("Or from not using the automatic import.");
+ }
+ ~~~
+
+ Both auto-insertions can be disabled with an attribute if necessary:
+
+ ~~~
+ // In the crate root:
+ #[no_std];
+ ~~~
+
+ ~~~
+ // In any module:
+ #[no_implicit_prelude];
+ ~~~
- ## The standard library
+ ## The standard library in detail
The Rust standard library provides runtime features required by the language,
including the task scheduler and memory allocators, as well as library
common traits ([`kinds`], [`ops`], [`cmp`], [`num`],
[`to_str`], [`clone`]), and complete bindings to the C standard library ([`libc`]).
- ### Standard Library injection and the Rust prelude
-
- `std` is imported at the topmost level of every crate by default, as
- if the first line of each crate was
-
- extern mod std;
-
- This means that the contents of std can be accessed from from any context
- with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
- etc.
-
- Additionally, `std` contains a `prelude` module that reexports many of the
- most common standard modules, types and traits. The contents of the prelude are
- imported into every *module* by default. Implicitly, all modules behave as if
- they contained the following prologue:
-
- use std::prelude::*;
+ The full documentation for `std` can be found here: [standard library].
+ [standard library]: std/index.html
[`std`]: std/index.html
[`bool`]: std/bool.html
[tuples]: std/tuple.html
[`clone`]: std/clone.html
[`libc`]: std/libc.html
+ ## The extra library
+
+ Rust also ships with the [extra library], an accumulation of
+ useful things, that are however not important enough
+ to deserve a place in the standard library.
+ You can use them by linking to `extra` with an `extern mod extra;`.
+
+ [extra library]: extra/index.html
+
+ Right now `extra` contains those definitions directly, but in the future it will likely just
+ re-export a bunch of 'officially blessed' crates that get managed with `rustpkg`.
+
# What next?
Now that you know the essentials, check out any of the additional
* [Macros][macros]
* [The foreign function interface][ffi]
* [Containers and iterators](tutorial-container.html)
+* [Error-handling and Conditions](tutorial-conditions.html)
- There is further documentation on the [wiki].
+ There is further documentation on the [wiki], however those tend to be even more out of date as this document.
[borrow]: tutorial-borrowed-ptr.html
[tasks]: tutorial-tasks.html