Skip to content

Commit 0a85296

Browse files
committed
---
yaml --- r: 6074 b: refs/heads/master c: aa01876 h: refs/heads/master v: v3
1 parent 4177b7f commit 0a85296

File tree

8 files changed

+269
-2
lines changed

8 files changed

+269
-2
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: e8e2cd44f48a6edcdd4477ab66f0fc5935ecd1a1
2+
refs/heads/master: aa01876c95a3f50ef6129f1501d97c7a6bb0e856

trunk/doc/tutorial/ffi.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Interacting with foreign code
2+
3+
FIXME to be written

trunk/doc/tutorial/index.md

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# Rust language tutorial
2+
3+
<div style="font-weight: bold; color: #a00;">Dev snapshot. Not yet suitable for public consumption.</div>

trunk/doc/tutorial/intro.md

+11
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,14 @@ function, `ret` for return.
4646
You should, however, not conclude that Rust is simply an evolution of
4747
C. As will become clear in the rest of this tutorial, it goes into
4848
quite a different direction.
49+
50+
## Conventions
51+
52+
Throughout the tutorial, words that indicate language keywords or
53+
identifiers defined in the example code are displayed in `code font`.
54+
55+
Code snippets are indented, and also shown in a monospace font. Not
56+
all snippets constitute whole programs. For brevity, we'll often show
57+
fragments of programs that don't compile on their own. To try them
58+
out, you'll have to wrap them in `fn main() { ... }`, and make sure
59+
they don't contain references to things that aren't actually defined.

trunk/doc/tutorial/mod.md

+222-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,224 @@
11
# Modules and crates
22

3-
FIXME include name resolution details
3+
The Rust namespace is divided in modules. Each source file starts with
4+
its own, empty module.
5+
6+
## Local modules
7+
8+
The `mod` keyword can be used to open a new, local module. In the
9+
example below, `chicken` lives in the module `farm`, so, unless you
10+
explicitly import it, you must refer to it by its long name,
11+
`farm::chicken`.
12+
13+
mod farm {
14+
fn chicken() -> str { "cluck cluck" }
15+
fn cow() -> str { "mooo" }
16+
}
17+
fn main() {
18+
log_err farm::chicken();
19+
}
20+
21+
Modules can be nested to arbitrary depth.
22+
23+
## Crates
24+
25+
The unit of independent compilation in Rust is the crate. Libraries
26+
tend to be packaged as crates, and your own programs may consist of
27+
one or more crates.
28+
29+
When compiling a single `.rs` file, the file acts as the whole crate.
30+
You can compile it with the `--lib` compiler switch to create a shared
31+
library, or without, provided that your file contains a `fn main`
32+
somewhere, to create an executable.
33+
34+
It is also possible to include multiple files in a crate. For this
35+
purpose, you create a `.rc` crate file, which references any number of
36+
`.rs` code files. A crate file could look like this:
37+
38+
#[link(name = "farm", vers = "2.5", author = "mjh")]
39+
mod cow;
40+
mod chicken;
41+
mod horse;
42+
43+
Compiling this file will cause `rustc` to look for files named
44+
`cow.rs`, `chicken.rs`, `horse.rs` in the same directory as the `.rc`
45+
file, compile them all together, and, depending on the presence of the
46+
`--lib` switch, output a shared library or an executable.
47+
48+
The `#[link(...)]` part provides meta information about the module,
49+
which other crates can use to load the right module. More about that
50+
in a moment.
51+
52+
To have a nested directory structure for your source files, you can
53+
nest mods in your `.rc` file:
54+
55+
mod poultry {
56+
mod chicken;
57+
mod turkey;
58+
}
59+
60+
The compiler will now look for `poultry/chicken.rs` and
61+
`poultry/turkey.rs`, and export their content in `poultry::chicken`
62+
and `poultry::turkey`. You can also provide a `poultry.rs` to add
63+
content to the `poultry` module itself.
64+
65+
## Using other crates
66+
67+
Having compiled a crate with `--lib`, you can use it in another crate
68+
with a `use` directive. We've already seen `use std` in several of the
69+
examples, which loads in the standard library.
70+
71+
`use` directives can appear in a crate file, or at the top level of a
72+
single-file `.rs` crate. They will cause the compiler to search its
73+
library search path (which you can extend with `-L` switch) for a Rust
74+
crate library with the right name. This name is deduced from the crate
75+
name in a platform-dependent way. The `farm` library will be called
76+
`farm.dll` on Windows, `libfarm.so` on Linux, and `libfarm.dylib` on
77+
OS X.
78+
79+
It is possible to provide more specific information when using an
80+
external crate.
81+
82+
use myfarm (name = "farm", vers = "2.7");
83+
84+
When a comma-separated list of name/value pairs is given after `use`,
85+
these are matched against the attributes provided in the `link`
86+
attribute of the crate file, and a crate is only used when the two
87+
match. A `name` value can be given to override the name used to search
88+
for the crate. So the above would import the `farm` crate under the
89+
local name `myfarm`.
90+
91+
Our example crate declared this set of `link` attributes:
92+
93+
#[link(name = "farm", vers = "2.5", author = "mjh")]
94+
95+
The version does not match the one provided in the `use` directive, so
96+
unless the compiler can find another crate with the right version
97+
somewhere, it will complain that no matching crate was found.
98+
99+
## A minimal example
100+
101+
Now for something that you can actually compile yourself. We have
102+
these two files:
103+
104+
// mylib.rs
105+
fn world() -> str { "world" }
106+
107+
// main.rs
108+
use mylib;
109+
fn main() { log_err "hello " + mylib::world(); }
110+
111+
FIXME the compiler currently complains about missing link metas when you compile this
112+
113+
Now compile and run like this (adjust to your platform if necessary):
114+
115+
> rustc --lib mylib.rs
116+
> rustc main.rs -L .
117+
> ./main
118+
"hello world"
119+
120+
## Importing
121+
122+
When using identifiers from other modules, it can get tiresome to
123+
qualify them with the full module path every time (especially when
124+
that path is several modules deep). Rust allows you to import
125+
identifiers at the top of a file or module.
126+
127+
use std;
128+
import std::io::println;
129+
fn main() {
130+
println("that was easy");
131+
}
132+
133+
It is also possible to import just the name of a module (`import
134+
std::io;`, then use `io::println`), import all identifiers exported by
135+
a given module (`import std::io::*`), or to import a specific set of
136+
identifiers (`import std::math::{min, max, pi}`).
137+
138+
It is also possible to rename an identifier when importing, using the
139+
`=` operator:
140+
141+
import prnt = std::io::println;
142+
143+
## Exporting
144+
145+
By default, a module exports everything that it defines. This can be
146+
restricted with `export` directives at the top of the module or file.
147+
148+
mod enc {
149+
export encrypt, decrypt;
150+
const super_secret_number: int = 10;
151+
fn encrypt(n: int) { n + super_secret_number }
152+
fn decrypt(n: int) { n - super_secret_number }
153+
}
154+
155+
This defines a rock-solid encryption algorithm. Code outside of the
156+
module can refer to the `enc::encrypt` and `enc::decrypt` identifiers
157+
just fine, but it does not have access to `enc::syper_secret_number`.
158+
159+
## Namespaces
160+
161+
Rust uses three different namespaces. One for modules, one for types,
162+
and one for values. This means that this code is valid:
163+
164+
mod buffalo {
165+
type buffalo = int;
166+
fn buffalo(buffalo: buffalo) -> buffalo { buffalo }
167+
}
168+
fn main() {
169+
let buffalo: buffalo::buffalo = 1;
170+
buffalo::buffalo(buffalo::buffalo(buffalo));
171+
}
172+
173+
You don't want to write things like that, but it *is* very practical
174+
to not have to worry about name clashes between types, values, and
175+
modules. This allows us to have a module `std::str`, for example, even
176+
though `str` is a built-in type name.
177+
178+
## Resolution
179+
180+
The resolution process in Rust simply goes up the chain of contexts,
181+
looking for the name in each context. Nested functions and modules
182+
create new contexts inside their parent function or module. A file
183+
that's part of a bigger crate will have that crate's context as parent
184+
context.
185+
186+
Identifiers can shadow each others. In this program, `x` is of type
187+
`int`:
188+
189+
type x = str;
190+
fn main() {
191+
type x = int;
192+
let x: int;
193+
}
194+
195+
An `import` directive will only import into the namespaces for which
196+
identifiers are actually found. Consider this example:
197+
198+
type bar = uint;
199+
mod foo { fn bar() {} }
200+
mod baz {
201+
import foo::bar;
202+
const x: bar = 20u;
203+
}
204+
205+
When resolving the type name `bar` in the `const` definition, the
206+
resolver will first look at the module context for `baz`. This has an
207+
import named `bar`, but that's a function, not a type, So it continues
208+
to the top level and finds a type named `bar` defined there.
209+
210+
Normally, multiple definitions of the same identifier in a scope are
211+
disallowed. Local variables defined with `let` are an exception to
212+
this—multiple `let` directives can redefine the same variable in a
213+
single scope. When resolving the name of such a variable, the most
214+
recent definition is used.
215+
216+
fn main() {
217+
let x = 10;
218+
let x = x + 10;
219+
assert x == 20;
220+
}
221+
222+
This makes it possible to rebind a variable without actually mutating
223+
it, which is mostly useful for destructuring (which can rebind, but
224+
not assign).

trunk/doc/tutorial/order

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ data
77
args
88
generic
99
mod
10+
ffi
11+
task

trunk/doc/tutorial/syntax.md

+25
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,27 @@ The double-colon (`::`) is used as a module separator, so
8686
`std::io::println` means 'the thing named `println` in the module
8787
named `io` in the module named `std`'.
8888

89+
Rust will normally emit warning about unused variables. These can be
90+
suppressed by using a variable name that starts with an underscore.
91+
92+
fn this_warns(x: int) {}
93+
fn this_doesnt(_x: int) {}
94+
95+
## Variable declaration
96+
97+
The `let` keyword, as we've seen, introduces a local variable. Global
98+
constants can be defined with `const`:
99+
100+
import std;
101+
const repeat: uint = 5u;
102+
fn main() {
103+
let count = 0u;
104+
while count < repeat {
105+
std::io::println("Hi!");
106+
count += 1u;
107+
}
108+
}
109+
89110
## Types
90111

91112
The `-> bool` in the last example is the way a function's return type
@@ -256,3 +277,7 @@ exists, convert the result of the expression to the given type.
256277
let x: float = 4.0;
257278
let y: uint = x as uint;
258279
assert y == 4u;
280+
281+
## Attributes
282+
283+
FIXME Briefly introduce attributes

trunk/doc/tutorial/task.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Tasks
2+
3+
FIXME to be written

0 commit comments

Comments
 (0)