From 31b240d6bcb81836fca2c2aa4076daa2aea587fe Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 11 Dec 2014 12:11:39 -0500 Subject: [PATCH] Add comments with type annotations. This will hopefully help people with their first steps in Rust. Fixes #16143. --- src/doc/guide.md | 72 +++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/src/doc/guide.md b/src/doc/guide.md index 21043cfef14..a054038ac89 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -417,6 +417,19 @@ 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`." +In future examples, we may annotate the type in a comment. The examples will +look like this: + +```{rust} +fn main() { + let x = 5i; // x: int +} +``` + +Note the similarities between this annotation and the syntax you use with `let`. +Including these kinds of comments is not idiomatic Rust, but we'll occasionally +include them to help you understand what the types that Rust infers are. + By default, bindings are **immutable**. This code will not compile: ```{ignore} @@ -435,7 +448,7 @@ error: re-assignment of immutable variable `x` If you want a binding to be mutable, you can use `mut`: ```{rust} -let mut x = 5i; +let mut x = 5i; // mut x: int x = 10i; ``` @@ -583,7 +596,7 @@ let y = if x == 5i { 10i } else { 15i -}; +}; // y: int ``` Which we can (and probably should) write like this: @@ -591,7 +604,7 @@ Which we can (and probably should) write like this: ```{rust} let x = 5i; -let y = if x == 5i { 10i } else { 15i }; +let y = if x == 5i { 10i } else { 15i }; // y: int ``` This reveals two interesting things about Rust: it is an expression-based @@ -927,8 +940,8 @@ destructuring. You can assign one tuple into another, if they have the same arity and contained types. ```rust -let mut x = (1i, 2i); -let y = (2i, 3i); +let mut x = (1i, 2i); // x: (int, int) +let y = (2i, 3i); // y: (int, int) x = y; ``` @@ -980,7 +993,7 @@ struct Point { } fn main() { - let origin = Point { x: 0i, y: 0i }; + let origin = Point { x: 0i, y: 0i }; // origin: Point println!("The origin is at ({}, {})", origin.x, origin.y); } @@ -1100,7 +1113,7 @@ fn main() { let x = 5i; let y = 10i; - let ordering = cmp(x, y); + let ordering = cmp(x, y); // ordering: Ordering if ordering == Less { println!("less"); @@ -1387,7 +1400,7 @@ Instead, it looks like this: ```{rust} for x in range(0i, 10i) { - println!("{}", x); + println!("{}", x); // x: int } ``` @@ -1422,8 +1435,8 @@ The other kind of looping construct in Rust is the `while` loop. It looks like this: ```{rust} -let mut x = 5u; -let mut done = false; +let mut x = 5u; // mut x: uint +let mut done = false; // mut done: bool while !done { x += x - 3; @@ -1519,7 +1532,7 @@ The first kind is a `&str`. This is pronounced a 'string slice.' String literals are of the type `&str`: ```{rust} -let string = "Hello there."; +let string = "Hello there."; // string: &str ``` This string is statically allocated, meaning that it's saved inside our @@ -1531,7 +1544,7 @@ A `String`, on the other hand, is an in-memory string. This string is growable, and is also guaranteed to be UTF-8. ```{rust} -let mut s = "Hello".to_string(); +let mut s = "Hello".to_string(); // mut s: String println!("{}", s); s.push_str(", world."); @@ -1587,16 +1600,19 @@ things. The most basic is the **array**, a fixed-size list of elements of the same type. By default, arrays are immutable. ```{rust} -let a = [1i, 2i, 3i]; -let mut m = [1i, 2i, 3i]; +let a = [1i, 2i, 3i]; // a: [int, ..3] +let mut m = [1i, 2i, 3i]; // mut m: [int, ..3] ``` You can create an array with a given number of elements, all initialized to the same value, with `[val, ..N]` syntax. The compiler ensures that arrays are always initialized. +There's a shorthand for initializing each element of an array to the same +value. In this example, each element of `a` will be initialized to `0i`: + ```{rust} -let a = [0i, ..20]; // Shorthand for array of 20 elements all initialized to 0 +let a = [0i, ..20]; // a: [int, ..20] ``` Arrays have type `[T,..N]`. We'll talk about this `T` notation later, when we @@ -1607,7 +1623,7 @@ You can get the number of elements in an array `a` with `a.len()`, and use number in order: ```{rust} -let a = [1i, 2, 3]; // Only the first item needs a type suffix +let a = [1i, 2, 3]; // Only the first item needs a type suffix println!("a has {} elements", a.len()); for e in a.iter() { @@ -1618,7 +1634,7 @@ for e in a.iter() { You can access a particular element of an array with **subscript notation**: ```{rust} -let names = ["Graydon", "Brian", "Niko"]; +let names = ["Graydon", "Brian", "Niko"]; // names: [&str, 3] println!("The second name is: {}", names[1]); ``` @@ -1636,7 +1652,7 @@ later). Vectors are to arrays what `String` is to `&str`. You can create them with the `vec!` macro: ```{rust} -let v = vec![1i, 2, 3]; +let v = vec![1i, 2, 3]; // v: Vec ``` (Notice that unlike the `println!` macro we've used in the past, we use square @@ -1647,8 +1663,10 @@ You can get the length of, iterate over, and subscript vectors just like arrays. In addition, (mutable) vectors can grow automatically: ```{rust} -let mut nums = vec![1i, 2, 3]; +let mut nums = vec![1i, 2, 3]; // mut nums: Vec + nums.push(4); + println!("The length of nums is now {}", nums.len()); // Prints 4 ``` @@ -1822,10 +1840,12 @@ use std::io; fn main() { println!("Type something!"); - let input = io::stdin() - .read_line() - .ok() - .expect("Failed to read line"); + // here, we'll show the types at each step + + let input = io::stdin() // std::io::stdio::StdinReader + .read_line() // IoResult + .ok() // Option + .expect("Failed to read line"); // String println!("{}", input); } @@ -1968,7 +1988,7 @@ use std::rand; fn main() { println!("Guess the number!"); - let secret_number = (rand::random() % 100i) + 1i; + let secret_number = (rand::random() % 100i) + 1i; // secret_number: int println!("The secret number is: {}", secret_number); @@ -2261,8 +2281,8 @@ In this case, we say `x` is a `uint` explicitly, so Rust is able to properly tell `random()` what to generate. In a similar fashion, both of these work: ```{rust,ignore} -let input_num = from_str::("5"); -let input_num: Option = from_str("5"); +let input_num = from_str::("5"); // input_num: Option +let input_num: Option = from_str("5"); // input_num: Option ``` Anyway, with us now converting our input to a number, our code looks like this: