Merge remote-tracking branch 'origin/master' into 0.11.0-release

Conflicts:
	src/libstd/lib.rs
This commit is contained in:
Alex Crichton 2014-07-02 11:08:21 -07:00
commit ff1dd44b40
715 changed files with 10358 additions and 8207 deletions

View file

@ -50,19 +50,19 @@ use libc::{c_int, size_t};
#[link(name = "snappy")]
extern {
fn snappy_compress(input: *u8,
fn snappy_compress(input: *const u8,
input_length: size_t,
compressed: *mut u8,
compressed_length: *mut size_t) -> c_int;
fn snappy_uncompress(compressed: *u8,
fn snappy_uncompress(compressed: *const u8,
compressed_length: size_t,
uncompressed: *mut u8,
uncompressed_length: *mut size_t) -> c_int;
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
fn snappy_uncompressed_length(compressed: *u8,
fn snappy_uncompressed_length(compressed: *const u8,
compressed_length: size_t,
result: *mut size_t) -> c_int;
fn snappy_validate_compressed_buffer(compressed: *u8,
fn snappy_validate_compressed_buffer(compressed: *const u8,
compressed_length: size_t) -> c_int;
}
# fn main() {}
@ -82,7 +82,7 @@ the allocated memory. The length is less than or equal to the capacity.
~~~~
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_validate_compressed_buffer(_: *u8, _: size_t) -> c_int { 0 }
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
# fn main() {}
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
unsafe {
@ -106,7 +106,7 @@ the true length after compression for setting the length.
~~~~
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_compress(a: *u8, b: size_t, c: *mut u8,
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
# d: *mut size_t) -> c_int { 0 }
# unsafe fn snappy_max_compressed_length(a: size_t) -> size_t { a }
# fn main() {}
@ -132,11 +132,11 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ
~~~~
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_uncompress(compressed: *u8,
# unsafe fn snappy_uncompress(compressed: *const u8,
# compressed_length: size_t,
# uncompressed: *mut u8,
# uncompressed_length: *mut size_t) -> c_int { 0 }
# unsafe fn snappy_uncompressed_length(compressed: *u8,
# unsafe fn snappy_uncompressed_length(compressed: *const u8,
# compressed_length: size_t,
# result: *mut size_t) -> c_int { 0 }
# fn main() {}
@ -418,7 +418,7 @@ Unsafe functions, on the other hand, advertise it to the world. An unsafe functi
this:
~~~~
unsafe fn kaboom(ptr: *int) -> int { *ptr }
unsafe fn kaboom(ptr: *const int) -> int { *ptr }
~~~~
This function can only be called from an `unsafe` block or another `unsafe` function.
@ -453,7 +453,7 @@ use std::ptr;
#[link(name = "readline")]
extern {
static mut rl_prompt: *libc::c_char;
static mut rl_prompt: *const libc::c_char;
}
fn main() {
@ -478,7 +478,7 @@ extern crate libc;
#[link(name = "kernel32")]
#[allow(non_snake_case_functions)]
extern "stdcall" {
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> libc::c_int;
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
}
# fn main() { }
~~~~

View file

@ -355,6 +355,7 @@ macro_rules! biased_match_rec (
_ => { $err }
}
);
// Produce the requested values
( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )
)
@ -364,7 +365,7 @@ macro_rules! biased_match (
( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
binds $bind_res:ident
) => (
let ( $( $bind_res ),* ) = biased_match_rec!(
let $bind_res = biased_match_rec!(
$( ($e) ~ ($p) else $err ; )*
binds $bind_res
);

View file

@ -245,7 +245,7 @@ extern crate green;
extern crate rustuv;
#[start]
fn start(argc: int, argv: **u8) -> int {
fn start(argc: int, argv: *const *const u8) -> int {
green::start(argc, argv, rustuv::event_loop, main)
}
@ -261,7 +261,9 @@ inside of an OS thread.
extern crate native;
#[start]
fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, main) }
fn start(argc: int, argv: *const *const u8) -> int {
native::start(argc, argv, main)
}
fn main() {}
~~~

View file

@ -457,6 +457,8 @@ the string in response. The child terminates when it receives `0`.
Here is the function that implements the child task:
~~~
#![allow(deprecated)]
use std::comm::DuplexStream;
# fn main() {
fn stringifier(channel: &DuplexStream<String, uint>) {
@ -481,6 +483,8 @@ response itself is simply the stringified version of the received value,
Here is the code for the parent task:
~~~
#![allow(deprecated)]
use std::comm::duplex;
# use std::task::spawn;
# use std::comm::DuplexStream;

View file

@ -79,7 +79,7 @@ let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
## Raw pointers
Rust offers two additional pointer types "raw pointers", written as
`*T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
`*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
respectively; indeed, one of their most common uses is for FFI,
interfacing with external C libraries.
@ -100,7 +100,7 @@ offered by the Rust language and libraries. For example, they
- lack any form of lifetimes, unlike `&`, and so the compiler cannot
reason about dangling pointers; and
- have no guarantees about aliasing or mutability other than mutation
not being allowed directly through a `*T`.
not being allowed directly through a `*const T`.
Fortunately, they come with a redeeming feature: the weaker guarantees
mean weaker restrictions. The missing restrictions make raw pointers
@ -131,13 +131,13 @@ unsafe, and neither is converting to an integer.
At runtime, a raw pointer `*` and a reference pointing to the same
piece of data have an identical representation. In fact, an `&T`
reference will implicitly coerce to an `*T` raw pointer in safe code
reference will implicitly coerce to an `*const T` raw pointer in safe code
and similarly for the `mut` variants (both coercions can be performed
explicitly with, respectively, `value as *T` and `value as *mut T`).
explicitly with, respectively, `value as *const T` and `value as *mut T`).
Going the opposite direction, from `*` to a reference `&`, is not
Going the opposite direction, from `*const` to a reference `&`, is not
safe. A `&T` is always valid, and so, at a minimum, the raw pointer
`*T` has to be a valid to a valid instance of type `T`. Furthermore,
`*const T` has to be a valid to a valid instance of type `T`. Furthermore,
the resulting pointer must satisfy the aliasing and mutability laws of
references. The compiler assumes these properties are true for any
references, no matter how they are created, and so any conversion from
@ -149,7 +149,7 @@ The recommended method for the conversion is
```
let i: u32 = 1;
// explicit cast
let p_imm: *u32 = &i as *u32;
let p_imm: *const u32 = &i as *const u32;
let mut m: u32 = 2;
// implicit coercion
let p_mut: *mut u32 = &mut m;
@ -256,7 +256,7 @@ impl<T: Send> Drop for Unique<T> {
// Copy the object out from the pointer onto the stack,
// where it is covered by normal Rust destructor semantics
// and cleans itself up, if necessary
ptr::read(self.ptr as *T);
ptr::read(self.ptr as *const T);
// clean-up our allocation
free(self.ptr as *mut c_void)
@ -267,12 +267,12 @@ impl<T: Send> Drop for Unique<T> {
// A comparison between the built-in `Box` and this reimplementation
fn main() {
{
let mut x = box 5;
let mut x = box 5i;
*x = 10;
} // `x` is freed here
{
let mut y = Unique::new(5);
let mut y = Unique::new(5i);
*y.borrow_mut() = 10;
} // `y` is freed here
}
@ -457,7 +457,7 @@ extern crate libc;
// Entry point for this program
#[start]
fn start(_argc: int, _argv: **u8) -> int {
fn start(_argc: int, _argv: *const *const u8) -> int {
0
}
@ -482,7 +482,7 @@ compiler's name mangling too:
extern crate libc;
#[no_mangle] // ensure that this symbol is called `main` in the output
pub extern fn main(argc: int, argv: **u8) -> int {
pub extern fn main(argc: int, argv: *const *const u8) -> int {
0
}
@ -540,8 +540,8 @@ use core::mem;
use core::raw::Slice;
#[no_mangle]
pub extern fn dot_product(a: *u32, a_len: u32,
b: *u32, b_len: u32) -> u32 {
pub extern fn dot_product(a: *const u32, a_len: u32,
b: *const u32, b_len: u32) -> u32 {
// Convert the provided arrays into Rust slices.
// The core::raw module guarantees that the Slice
// structure has the same memory layout as a &[T]
@ -573,7 +573,7 @@ extern fn begin_unwind(args: &core::fmt::Arguments,
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
# #[start] fn start(argc: int, argv: **u8) -> int { 0 }
# #[start] fn start(argc: int, argv: *const *const u8) -> int { 0 }
# fn main() {}
```
@ -595,7 +595,7 @@ standard library itself.
> parts of the language may never be full specified and so details may
> differ wildly between implementations (and even versions of `rustc`
> itself).
>
>
> Furthermore, this is just an overview; the best form of
> documentation for specific instances of these features are their
> definitions and uses in `std`.
@ -627,7 +627,7 @@ via a declaration like
extern "rust-intrinsic" {
fn transmute<T, U>(x: T) -> U;
fn offset<T>(dst: *T, offset: int) -> *T;
fn offset<T>(dst: *const T, offset: int) -> *const T;
}
```
@ -677,8 +677,8 @@ unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
}
#[start]
fn main(argc: int, argv: **u8) -> int {
let x = box 1;
fn main(argc: int, argv: *const *const u8) -> int {
let x = box 1i;
0
}

View file

@ -160,7 +160,7 @@ Save the file, and then type this into your terminal window:
```{bash}
$ rustc hello_world.rs
$ ./hello_world # just 'hello_world' on Windows
$ ./hello_world # or hello_world.exe on Windows
Hello, world
```
@ -243,7 +243,7 @@ There are now two files: our source code, with the `.rs` extension, and the
executable (`hello_world.exe` on Windows, `hello_world` everywhere else)
```{bash}
$ ./hello_world # or ./hello_world.exe on Windows
$ ./hello_world # or hello_world.exe on Windows
```
This prints out our `Hello, world!` text to our terminal.
@ -285,8 +285,9 @@ At first, your program doesn't have any dependencies, so we'll only be using
the first part of its functionality. Eventually, we'll add more. Since we
started off by using Cargo, it'll be easy to add later.
Let's convert Hello World to Cargo. The first thing we need to do is install
it. To do this, we need to build it from source. There are no binaries yet.
Let's convert Hello World to Cargo. The first thing we need to do to begin using Cargo
is to install Cargo. To do this, we need to build it from source. There are no binaries
yet.
First, let's go back to our projects directory. We don't want Cargo to
live in our project!
@ -412,6 +413,202 @@ rest of your Rust career.
Next, we'll learn more about Rust itself, by starting to write a more complicated
program. We hope you want to do more with Rust than just print "Hello, world!"
## Guessing Game
Let's write a bigger program in Rust. We could just go through a laundry list
of Rust features, but that's boring. Instead, we'll learn more about how to
code in Rust by writing a few example projects.
For our first project, we'll implement a classic beginner programming problem:
the guessing game. Here's how it works: Our program will generate a random
integer between one and a hundred. It will then prompt us to enter a guess.
Upon entering our guess, it will tell us if we're too low or too high. Once we
guess correctly, it will congratulate us, and print the number of guesses we've
taken to the screen. Sound good? It sounds easy, but it'll end up showing off a
number of basic features of Rust.
### Set up
Let's set up a new project. Go to your projects directory, and make a new
directory for the project, as well as a `src` directory for our code:
```{bash}
$ cd ~/projects
$ mkdir guessing_game
$ cd guessing_game
$ mkdir src
```
Great. Next, let's make a `Cargo.toml` file so Cargo knows how to build our
project:
```{ignore}
[package]
name = "guessing_game"
version = "0.1.0"
authors = [ "someone@example.com" ]
[[bin]]
name = "guessing_game"
```
Finally, we need our source file. Let's just make it hello world for now, so we
can check that our setup works. In `src/guessing_game.rs`:
```{rust}
fn main() {
println!("Hello world!");
}
```
Let's make sure that worked:
```{bash}
$ cargo build
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
$
```
Excellent! Open up your `src/guessing_game.rs` again. We'll be writing all of
our code in this file. The next section of the tutorial will show you how to
build multiple-file projects.
## Variable bindings
The first thing we'll learn about are 'variable bindings.' They look like this:
```{rust}
let x = 5i;
```
In many languages, this is called a 'variable.' But Rust's variable bindings
have a few tricks up their sleeves. Rust has a very powerful feature called
'pattern matching' that we'll get into detail with later, but the left
hand side of a `let` expression is a full pattern, not just a variable name.
This means we can do things like:
```{rust}
let (x, y) = (1i, 2i);
```
After this expression is evaluated, `x` will be one, and `y` will be two.
Patterns are really powerful, but this is about all we can do with them so far.
So let's just keep this in the back of our minds as we go forward.
By the way, in these examples, `i` indicates that the number is an integer.
Rust is a statically typed language, which means that we specify our types up
front. So why does our first example compile? Well, Rust has this thing called
"[Hindley-Milner type
inference](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)",
named after some really smart type theorists. If you clicked that link, don't
be scared: what this means for you is that Rust will attempt to infer the types
in your program, and it's pretty good at it. If it can infer the type, Rust
doesn't require you to actually type it out.
We can add the type if we want to. Types come after a colon (`:`):
```{rust}
let x: int = 5;
```
If I asked you to read this out loud to the rest of the class, you'd say "`x`
is a binding with the type `int` and the value `five`." Rust requires you to
initialize the binding with a value before you're allowed to use it. If
we try...
```{ignore}
let x;
```
...we'll get an error:
```{ignore}
src/guessing_game.rs:2:9: 2:10 error: cannot determine a type for this local variable: unconstrained type
src/guessing_game.rs:2 let x;
^
```
Giving it a type will compile, though:
```{ignore}
let x: int;
```
Let's try it out. Change your `src/guessing_game.rs` file to look like this:
```{rust}
fn main() {
let x: int;
println!("Hello world!");
}
```
You can use `cargo build` on the command line to build it. You'll get a warning,
but it will still print "Hello, world!":
```{ignore,notrust}
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
src/guessing_game.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
src/guessing_game.rs:2 let x: int;
^
```
Rust warns us that we never use the variable binding, but since we never use it,
no harm, no foul. Things change if we try to actually use this `x`, however. Let's
do that. Change your program to look like this:
```{rust,ignore}
fn main() {
let x: int;
println!("The value of x is: {}", x);
}
```
And try to build it. You'll get an error:
```{bash}
$ cargo build
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
src/guessing_game.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
src/guessing_game.rs:4 println!("The value of x is: {}", x);
^
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
src/guessing_game.rs:4:5: 4:42 note: expansion site
error: aborting due to previous error
Could not execute process `rustc src/guessing_game.rs --crate-type bin --out-dir /home/you/projects/guessing_game/target -L /home/you/projects/guessing_game/target -L /home/you/projects/guessing_game/target/deps` (status=101)
```
Rust will not let us use a value that has not been initialized. So why let us
declare a binding without initializing it? You'd think our first example would
have errored. Well, Rust is smarter than that. Before we get to that, let's talk
about this stuff we've added to `println!`.
If you include two curly braces (`{}`, some call them moustaches...) in your
string to print, Rust will interpret this as a request to interpolate some sort
of value. **String interpolation** is a computer science term that means "stick
in the middle of a string." We add a comma, and then `x`, to indicate that we
want `x` to be the value we're interpolating. The comma is used to separate
arguments we pass to functions and macros, if you're passing more than one.
When you just use the double curly braces, Rust will attempt to display the
value in a meaningful way by checking out its type. If you want to specify the
format in a more detailed manner, there are a [wide number of options
available](/std/fmt/index.html). Fow now, we'll just stick to the default:
integers aren't very complicated to print.
So, we've cleared up all of the confusion around bindings, with one exception:
why does Rust let us declare a variable binding without an initial value if we
must initialize the binding before we use it? And how does it know that we have
or have not initialized the binding? For that, we need to learn our next
concept: `if`.
## If
## Functions
@ -420,16 +617,6 @@ return
comments
## Testing
attributes
stability markers
## Crates and Modules
visibility
## Compound Data Types
Tuples
@ -450,10 +637,35 @@ loop
break/continue
iterators
## Guessing Game: complete
At this point, you have successfully built the Guessing Game! Congratulations!
For reference, [We've placed the sample code on
GitHub](https://github.com/steveklabnik/guessing_game).
You've now learned the basic syntax of Rust. All of this is relatively close to
various other programming languages you have used in the past. These
fundamental syntactical and semantic elements will form the foundation for the
rest of your Rust education.
Now that you're an expert at the basics, it's time to learn about some of
Rust's more unique features.
## iterators
## Lambdas
## Testing
attributes
stability markers
## Crates and Modules
visibility
## Generics
## Traits

View file

@ -133,7 +133,7 @@ Check it out:
```
fn dangling() -> Box<int> {
let i = box 1234;
let i = box 1234i;
return i;
}
@ -143,8 +143,8 @@ fn add_one() -> int {
}
```
Now instead of a stack allocated `1234`,
we have a heap allocated `box 1234`.
Now instead of a stack allocated `1234i`,
we have a heap allocated `box 1234i`.
Whereas `&` borrows a pointer to existing memory,
creating an owned box allocates memory on the heap and places a value in it,
giving you the sole pointer to that memory.
@ -152,7 +152,7 @@ You can roughly compare these two lines:
```
// Rust
let i = box 1234;
let i = box 1234i;
```
```cpp
@ -252,7 +252,7 @@ fn main() {
}
```
This will result an error indicating that the value is no longer in scope:
The compiler will produce an error indicating that the value is no longer in scope:
```text
concurrency.rs:12:20: 12:27 error: use of moved value: 'numbers'

View file

@ -442,17 +442,14 @@ of integer literal suffix:
The type of an _unsuffixed_ integer literal is determined by type inference.
If an integer type can be _uniquely_ determined from the surrounding program
context, the unsuffixed integer literal has that type. If the program context
underconstrains the type, the unsuffixed integer literal's type is `int`; if
the program context overconstrains the type, it is considered a static type
error.
underconstrains the type, it is considered a static type error;
if the program context overconstrains the type,
it is also considered a static type error.
Examples of integer literals of various forms:
~~~~
123; 0xff00; // type determined by program context
// defaults to int in absence of type
// information
123i; // type int
123u; // type uint
123_u; // type uint
0xff_u8; // type u8
@ -469,8 +466,10 @@ A _floating-point literal_ has one of two forms:
second decimal literal.
* A single _decimal literal_ followed by an _exponent_.
By default, a floating-point literal has a generic type, but will fall back to
`f64`. A floating-point literal may be followed (immediately, without any
By default, a floating-point literal has a generic type,
and, like integer literals, the type must be uniquely determined
from the context.
A floating-point literal may be followed (immediately, without any
spaces) by a _floating-point suffix_, which changes the type of the literal.
There are two floating-point suffixes: `f32`, and `f64` (the 32-bit and 64-bit
floating point types).
@ -478,8 +477,8 @@ floating point types).
Examples of floating-point literals of various forms:
~~~~
123.0; // type f64
0.1; // type f64
123.0f64; // type f64
0.1f64; // type f64
0.1f32; // type f32
12E+99_f64; // type f64
~~~~
@ -1614,7 +1613,7 @@ extern crate libc;
use libc::{c_char, FILE};
extern {
fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE;
}
# fn main() {}
~~~~
@ -2700,9 +2699,9 @@ must be a constant expression that can be evaluated at compile time, such
as a [literal](#literals) or a [static item](#static-items).
~~~~
[1, 2, 3, 4];
[1i, 2, 3, 4];
["a", "b", "c", "d"];
[0, ..128]; // vector with 128 zeros
[0i, ..128]; // vector with 128 zeros
[0u8, 0u8, 0u8, 0u8];
~~~~
@ -2881,7 +2880,7 @@ equals sign (`=`) and an [rvalue](#lvalues-rvalues-and-temporaries) expression.
Evaluating an assignment expression [either copies or moves](#moved-and-copied-types) its right-hand operand to its left-hand operand.
~~~~
# let mut x = 0;
# let mut x = 0i;
# let y = 0;
x = y;
@ -2932,7 +2931,7 @@ paren_expr : '(' expr ')' ;
An example of a parenthesized expression:
~~~~
let x = (2 + 3) * 4;
let x: int = (2 + 3) * 4;
~~~~
@ -3016,7 +3015,7 @@ conditional expression evaluates to `false`, the `while` expression completes.
An example:
~~~~
let mut i = 0;
let mut i = 0u;
while i < 10 {
println!("hello");
@ -3262,7 +3261,7 @@ Patterns can also dereference pointers by using the `&`,
on `x: &int` are equivalent:
~~~~
# let x = &3;
# let x = &3i;
let y = match *x { 0 => "zero", _ => "some" };
let z = match x { &0 => "zero", _ => "some" };
@ -3285,7 +3284,7 @@ A range of values may be specified with `..`.
For example:
~~~~
# let x = 2;
# let x = 2i;
let message = match x {
0 | 1 => "not many",

View file

@ -103,6 +103,17 @@ rustdoc can also generate JSON, for consumption by other tools, with
`rustdoc --output-format json`, and also consume already-generated JSON with
`rustdoc --input-format json`.
rustdoc also supports personalizing the output from crates' documentation,
similar to markdown options.
- `--html-in-header FILE`: includes the contents of `FILE` at the
end of the `<head>...</head>` section.
- `--html-before-content FILE`: includes the contents of `FILE`
directly after `<body>`, before the rendered content (including the
search bar).
- `--html-after-content FILE`: includes the contents of `FILE`
after all the rendered content.
# Using the Documentation
The web pages generated by rustdoc present the same logical hierarchy that one
@ -238,16 +249,16 @@ detected by a `.md` or `.markdown` extension.
There are 4 options to modify the output that Rustdoc creates.
- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`.
- `--markdown-in-header FILE`: includes the contents of `FILE` at the
- `--html-in-header FILE`: includes the contents of `FILE` at the
end of the `<head>...</head>` section.
- `--markdown-before-content FILE`: includes the contents of `FILE`
- `--html-before-content FILE`: includes the contents of `FILE`
directly after `<body>`, before the rendered content (including the
title).
- `--markdown-after-content FILE`: includes the contents of `FILE`
- `--html-after-content FILE`: includes the contents of `FILE`
directly before `</body>`, after all the rendered content.
All of these can be specified multiple times, and they are output in
the order in which they are specified. The first line of the file must
the order in which they are specified. The first line of the file being rendered must
be the title, prefixed with `%` (e.g. this page has `% Rust
Documentation` on the first line).

View file

@ -262,7 +262,7 @@ write function, variable, and module names with lowercase letters, using
underscores where they help readability, while writing types in camel case.
~~~
let my_variable = 100;
let my_variable = 100i;
type MyType = int; // primitive types are _not_ camel case
~~~
@ -276,7 +276,7 @@ write a piece of code like this:
~~~~
# let item = "salad";
let price;
let price: f64;
if item == "salad" {
price = 3.50;
} else if item == "muffin" {
@ -290,7 +290,7 @@ But, in Rust, you don't have to repeat the name `price`:
~~~~
# let item = "salad";
let price =
let price: f64 =
if item == "salad" {
3.50
} else if item == "muffin" {
@ -337,11 +337,10 @@ suffix that can be used to indicate the type of a literal: `i` for `int`,
In the absence of an integer literal suffix, Rust will infer the
integer type based on type annotations and function signatures in the
surrounding program. In the absence of any type information at all,
Rust will assume that an unsuffixed integer literal has type
`int`.
Rust will report an error and request that the type be specified explicitly.
~~~~
let a = 1; // `a` is an `int`
let a: int = 1; // `a` is an `int`
let b = 10i; // `b` is an `int`, due to the `i` suffix
let c = 100u; // `c` is a `uint`
let d = 1000i32; // `d` is an `i32`
@ -475,7 +474,7 @@ against each pattern in order until one matches. The matching pattern
executes its corresponding arm.
~~~~
let my_number = 1;
let my_number = 1i;
match my_number {
0 => println!("zero"),
1 | 2 => println!("one or two"),
@ -501,7 +500,7 @@ matches any single value. (`..`) is a different wildcard that can match
one or more fields in an `enum` variant.
~~~
# let my_number = 1;
# let my_number = 1i;
match my_number {
0 => { println!("zero") }
_ => { println!("something else") }
@ -584,7 +583,7 @@ keyword `break` aborts the loop, and `continue` aborts the current
iteration and continues with the next.
~~~~
let mut cake_amount = 8;
let mut cake_amount = 8i;
while cake_amount > 0 {
cake_amount -= 1;
}
@ -944,7 +943,7 @@ The `box` operator performs memory allocation on the heap:
~~~~
{
// an integer allocated on the heap
let y = box 10;
let y = box 10i;
}
// the destructor frees the heap memory as soon as `y` goes out of scope
~~~~
@ -1165,7 +1164,7 @@ let z = x;
The mutability of a value may be changed by moving it to a new owner:
~~~~
let r = box 13;
let r = box 13i;
let mut s = r; // box becomes mutable
*s += 1;
let t = s; // box becomes immutable
@ -1285,9 +1284,9 @@ Using the generic `List<T>` works much like before, thanks to type inference:
# Cons(value, box xs)
# }
let mut xs = Nil; // Unknown type! This is a `List<T>`, but `T` can be anything.
xs = prepend(xs, 10); // Here the compiler infers `xs`'s type as `List<int>`.
xs = prepend(xs, 15);
xs = prepend(xs, 20);
xs = prepend(xs, 10i); // Here the compiler infers `xs`'s type as `List<int>`.
xs = prepend(xs, 15i);
xs = prepend(xs, 20i);
~~~
The code sample above demonstrates type inference making most type annotations optional. It is
@ -1410,12 +1409,12 @@ Beyond the properties granted by the size, an owned box behaves as a regular
value by inheriting the mutability and lifetime of the owner:
~~~~
let x = 5; // immutable
let mut y = 5; // mutable
let x = 5i; // immutable
let mut y = 5i; // mutable
y += 2;
let x = box 5; // immutable
let mut y = box 5; // mutable
let x = box 5i; // immutable
let mut y = box 5i; // mutable
*y += 2; // the `*` operator is needed to access the contained value
~~~~
@ -1507,7 +1506,7 @@ freezing enforced statically at compile-time. An example of a non-`Freeze` type
is [`RefCell<T>`][refcell].
~~~~
let mut x = 5;
let mut x = 5i;
{
let y = &x; // `x` is now frozen. It cannot be modified or re-assigned.
}
@ -1523,8 +1522,8 @@ Rust uses the unary star operator (`*`) to access the contents of a
box or pointer, similarly to C.
~~~
let owned = box 10;
let borrowed = &20;
let owned = box 10i;
let borrowed = &20i;
let sum = *owned + *borrowed;
~~~
@ -1534,9 +1533,9 @@ assignments. Such an assignment modifies the value that the pointer
points to.
~~~
let mut owned = box 10;
let mut owned = box 10i;
let mut value = 20;
let mut value = 20i;
let borrowed = &mut value;
*owned = *borrowed + 100;
@ -1654,12 +1653,12 @@ Unicode code points, so they cannot be freely mutated without the ability to
alter the length.
~~~
let mut xs = [1, 2, 3];
let mut xs = [1i, 2i, 3i];
let view = xs.mut_slice(0, 2);
view[0] = 5;
// The type of a mutable slice is written as `&mut [T]`
let ys: &mut [int] = &mut [1, 2, 3];
let ys: &mut [int] = &mut [1i, 2i, 3i];
~~~
Square brackets denote indexing into a slice or fixed-size vector: