Skip to content

Commit df34fe9

Browse files
committed
doc: Trim down the tutorial a little more
1 parent 9eaaceb commit df34fe9

File tree

1 file changed

+55
-72
lines changed

1 file changed

+55
-72
lines changed

doc/tutorial.md

Lines changed: 55 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -303,14 +303,6 @@ The double-colon (`::`) is used as a module separator, so
303303
`io::println` means 'the thing named `println` in the module
304304
named `io`.
305305

306-
Rust will normally emit warnings about unused variables. These can be
307-
suppressed by using a variable name that starts with an underscore.
308-
309-
~~~~
310-
fn this_warns(x: int) {}
311-
fn this_doesnt(_x: int) {}
312-
~~~~
313-
314306
## Variable declaration
315307

316308
The `let` keyword, as we've seen, introduces a local variable. Local
@@ -319,11 +311,11 @@ a local variable that can be reassigned. Global constants can be
319311
defined with `const`:
320312

321313
~~~~
322-
const repeat: int = 5;
314+
const REPEAT: int = 5;
323315
fn main() {
324316
let hi = "Hi!";
325317
let mut count = 0;
326-
while count < repeat {
318+
while count < REPEAT {
327319
io::println(hi);
328320
count += 1;
329321
}
@@ -340,28 +332,6 @@ let my_favorite_value: int = my_favorite_value as int;
340332

341333
## Types
342334

343-
The `-> bool` in the `is_four` example is the way a function's return
344-
type is written. For functions that do not return a meaningful value
345-
(these conceptually return nil in Rust), you can optionally say `->
346-
()` (`()` is how nil is written), but usually the return annotation is
347-
simply left off, as in the `fn main() { ... }` examples we've seen
348-
earlier.
349-
350-
Every argument to a function must have its type declared (for example,
351-
`x: int`). Inside the function, type inference will be able to
352-
automatically deduce the type of most locals (generic functions, which
353-
we'll come back to later, will occasionally need additional
354-
annotation). Locals can be written either with or without a type
355-
annotation:
356-
357-
~~~~
358-
// The type of this vector will be inferred based on its use.
359-
let x = [];
360-
# vec::map(x, fn&(&&_y:int) -> int { _y });
361-
// Explicitly say this is a vector of zero integers.
362-
let y: [int * 0] = [];
363-
~~~~
364-
365335
The basic types are written like this:
366336

367337
`()`
@@ -407,16 +377,16 @@ more detail later on (the `T`s here stand for any other type):
407377
`@T`, `~T`, `&T`
408378
: Pointer types.
409379

410-
The size of some types can vary when your program runs. Because of this, you
411-
don't manipulate them only by pointer, never directly. For instance, you
412-
can't refer to a string (`str`); instead you refer to a pointer to a string
413-
(`@str`, `~str`, or `&str`). These *dynamically-sized* types const of:
380+
Some types can only be manipulated by pointer, never directly. For instance,
381+
you cannot refer to a string (`str`); instead you refer to a pointer to a
382+
string (`@str`, `~str`, or `&str`). These *dynamically-sized* types consist
383+
of:
414384

415385
`fn(arg1: T1, arg2: T2) -> T3`
416386
: Function types.
417387

418388
`str`
419-
: String type. A string contains a UTF-8 encoded sequence of characters.
389+
: String type (in UTF-8).
420390

421391
`[T]`
422392
: Vector with unknown size (also called a slice).
@@ -437,6 +407,28 @@ error. Read about [single-variant enums](#single_variant_enum)
437407
further on if you need to create a type name that's not just a
438408
synonym.
439409

410+
## Using types
411+
412+
The `-> bool` in the `is_four` example is the way a function's return
413+
type is written. For functions that do not return a meaningful value,
414+
you can optionally say `-> ()`, but usually the return annotation is simply
415+
left off, as in the `fn main() { ... }` examples we've seen earlier.
416+
417+
Every argument to a function must have its type declared (for example,
418+
`x: int`). Inside the function, type inference will be able to
419+
automatically deduce the type of most locals (generic functions, which
420+
we'll come back to later, will occasionally need additional
421+
annotation). Locals can be written either with or without a type
422+
annotation:
423+
424+
~~~~
425+
// The type of this vector will be inferred based on its use.
426+
let x = [];
427+
# vec::map(x, fn&(&&_y:int) -> int { _y });
428+
// Explicitly say this is a vector of zero integers.
429+
let y: [int * 0] = [];
430+
~~~~
431+
440432
## Numeric literals
441433

442434
Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
@@ -478,20 +470,20 @@ between double quotes (`"hello"`). Rust strings may contain newlines.
478470

479471
## Operators
480472

481-
Rust's set of operators contains very few surprises. Binary arithmetic
482-
is done with `*`, `/`, `%`, `+`, and `-` (multiply, divide, remainder,
483-
plus, minus). `-` is also a unary prefix operator that does negation. As in C,
484-
the bit operators `>>`, `<<`, `&`, `|`, and `^` are supported.
473+
Rust's set of operators contains very few surprises. Arithmetic is done with
474+
`*`, `/`, `%`, `+`, and `-` (multiply, divide, remainder, plus, minus). `-` is
475+
also a unary prefix operator that does negation. As in C, the bit operators
476+
`>>`, `<<`, `&`, `|`, and `^` are also supported.
485477

486-
Note that, if applied an integer value, `!` inverts all the bits.
478+
Note that, if applied to an integer value, `!` flips all the bits (like `~` in
479+
C).
487480

488481
The comparison operators are the traditional `==`, `!=`, `<`, `>`,
489482
`<=`, and `>=`. Short-circuiting (lazy) boolean operators are written
490483
`&&` (and) and `||` (or).
491484

492-
For type casting, Rust uses the binary `as` operator, which has high
493-
precedence, just lower than multiplication and division. It takes an
494-
expression on the left side, and a type on the right side, and will,
485+
For type casting, Rust uses the binary `as` operator. It takes an
486+
expression on the left side and a type on the right side and will,
495487
if a meaningful conversion exists, convert the result of the
496488
expression to the given type.
497489

@@ -508,11 +500,12 @@ more likely to be what you expect (unless you are a C veteran).
508500

509501
## Syntax extensions
510502

511-
*Syntax extensions* are special syntax that is not built into the language,
512-
but are instead provided by the libraries. To make it clear when a syntax
513-
extension is being used, their names all end with `!`. The standard library
514-
defines a few syntax extensions. The most useful one is `fmt!`, a
515-
`sprintf`-style text formatter that is expanded at compile time.
503+
*Syntax extensions* are special forms that are not built into the language,
504+
but are instead provided by the libraries. To make it clear to the reader when
505+
a syntax extension is being used, the names of all syntax extensions end with
506+
`!`. The standard library defines a few syntax extensions, the most useful of
507+
which is `fmt!`, a `sprintf`-style text formatter that is expanded at compile
508+
time.
516509

517510
~~~~
518511
io::println(fmt!("%s is %d", ~"the answer", 42));
@@ -524,7 +517,8 @@ don't match the types of the arguments.
524517

525518
[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf
526519

527-
You can define your own syntax extensions via macros.
520+
You can define your own syntax extensions with the macro system, which is out
521+
of scope of this tutorial.
528522

529523
# Control structures
530524

@@ -581,8 +575,8 @@ construct when it is finished.
581575
The part to the left of the arrow `=>` is called the *pattern*. Literals are
582576
valid patterns and will match only their own value. The pipe operator
583577
(`|`) can be used to assign multiple patterns to a single arm. Ranges
584-
of numeric literal patterns can be expressed with `..`. The underscore
585-
(`_`) is a wildcard pattern that matches everything.
578+
of numeric literal patterns can be expressed with two dots, as in `M..N`. The
579+
underscore (`_`) is a wildcard pattern that matches everything.
586580

587581
The patterns in an match arm are followed by a fat arrow, `=>`, then an
588582
expression to evaluate. Each case is separated by commas. It's often
@@ -601,10 +595,9 @@ match my_number {
601595
}
602596
~~~
603597

604-
If the arm with the wildcard pattern was left off in the above
605-
example, the typechecker would reject it at compile time. `match`
606-
constructs must be exhaustive: they must have an arm covering every
607-
possible case.
598+
`match` constructs must be *exhaustive*: they must have an arm covering every
599+
possible case. For example, if the arm with the wildcard pattern was left off
600+
in the above example, the typechecker would reject it.
608601

609602
A powerful application of pattern matching is *destructuring*, where
610603
you use the matching to get at the contents of data types. Remember
@@ -632,11 +625,11 @@ an expression of type `bool` that determines, after the pattern is
632625
found to match, whether the arm is taken or not. The variables bound
633626
by the pattern are available in this guard expression.
634627

635-
## Destructuring let
628+
## Let
636629

637-
To a limited extent, it is possible to use destructuring patterns when
638-
declaring a variable with `let`. For example, you can say this to
639-
extract the fields from a tuple:
630+
You've already seen simple `let` bindings. `let` is also a little fancier: it
631+
is possible to use destructuring patterns in it. For example, you can say this
632+
to extract the fields from a tuple:
640633

641634
~~~~
642635
# fn get_tuple_of_two_ints() -> (int, int) { (1, 1) }
@@ -646,7 +639,7 @@ let (a, b) = get_tuple_of_two_ints();
646639
This will introduce two new variables, `a` and `b`, bound to the
647640
content of the tuple.
648641

649-
You may only use irrefutable patterns—patterns that can never fail to
642+
You may only use *irrefutable* patterns—patterns that can never fail to
650643
match—in let bindings. Other types of patterns, such as literals, are
651644
not allowed.
652645

@@ -736,16 +729,6 @@ fn do_nothing_the_hard_way() -> () { return (); }
736729
fn do_nothing_the_easy_way() { }
737730
~~~~
738731

739-
Some functions (such as the C function `exit`) never return normally.
740-
In Rust, these are annotated with the pseudo-return type '`!`':
741-
742-
~~~~
743-
fn dead_end() -> ! { fail }
744-
~~~~
745-
746-
Using `!` in your code instead of making up a return type helps the compiler
747-
avoid spurious error messages.
748-
749732
# Basic datatypes
750733

751734
The core datatypes of Rust are structs, enums (tagged unions, algebraic data

0 commit comments

Comments
 (0)