Loading rust_03_rules...
fn main() { let a: i32 = 20; // signed, 32-bit let b: u8 = 5; // unsigned, 8-bit let c: f32 = 12.34; // floating-point, 32-bits let d: f64 = 56.78; // floating-point, 64-bits println!("a={} b={} c={} d={}", a, b, c, d); } /* a=20 b=5 c=12.34 d=56.78 */
fn main() { let a = 20_i32; // signed, 32-bit let b = 5_u8; // unsigned, 8-bit let c = 12.34_f32; // floating-point, 32-bits let d = 56.78_f64; // floating-point, 64-bits println!("a={} b={} c={} d={}", a, b, c, d); } /* a=20 b=5 c=12.34 d=56.78 */
rustup doc --book“3.2. Data Types”
rustup doc --rust-by-example“2. Primitives” “5.2. Literals”
rustup doc --std 'f32',
rustup doc --std 'f64'
rustup doc --std 'u8',
rustup doc --std 'i8'
rustup doc --std 'u16',
rustup doc --std 'i16'
rustup doc --std 'u32',
rustup doc --std 'i32'
rustup doc --std 'u64',
rustup doc --std 'i64'
rustup doc --std 'u128',
rustup doc --std 'i128'
rustup doc --std 'usize',
rustup doc --std 'isize'
rustup doc --reference“10.1.2. Numeric types”
#![allow(dead_code)] // silences some warnings
#[derive(Debug)] // provides debug formating for our own type struct Point { x: i32, y: i32, color: String, }
fn main() { let my_integer = 123; println!("my_integer, standard: {}", my_integer); println!("my_integer, debug: {:?}", my_integer); // let my_real = 45.67; println!(" my_real, standard: {}", my_real); println!(" my_real, debug: {:?}", my_real); // let my_str = "This is a sentence."; println!(" my_str, standard: {}", my_str); println!(" my_str, debug: {:?}", my_str); // let my_tuple = (98, 76.54, "hello"); // println!(" my_tuple, standard: {}", my_tuple); // unavailable println!(" my_tuple, debug: {:?}", my_tuple); // let my_array = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9]; // println!(" my_array, standard: {}", my_array); // unavailable println!(" my_array, debug: {:?}", my_array); // let my_vector = vec![10, 20, 30, 40, 50, 60, 70, 80, 90]; // println!(" my_vector, standard: {}", my_vector); // unavailable println!(" my_vector, debug: {:?}", my_vector); // let my_point = Point { x: 12, y: 34, color: "red".to_owned(), }; // println!(" my_point, standard: {}", my_point); // unavailable println!(" my_point, debug: {:?}", my_point); } /* my_integer, standard: 123 my_integer, debug: 123 my_real, standard: 45.67 my_real, debug: 45.67 my_str, standard: This is a sentence. my_str, debug: "This is a sentence." my_tuple, debug: (98, 76.54, "hello") my_array, debug: [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9] my_vector, debug: [10, 20, 30, 40, 50, 60, 70, 80, 90] my_point, debug: Point { x: 12, y: 34, color: "red" } */
rustup doc --rust-by-example“1.2. Formatted print”
rustup doc --std 'std::println!'
fn main() { let a = 10_i32; // let b: f64 = a; // error, expected `f64`, found `i32` let b: f64 = a as f64; // explicit conversion from i32 to f64 // let c = a + b + 0.1; // error, no implementation for `i32 + f64` let c = a as f64 + b + 0.1; // explicit conversion from i32 to f64 let d = a + b as i32; // explicit conversion from f64 to i32 println!("a={} b={} c={} d={}", a, b, c, d); } /* a=10 b=10 c=20.1 d=20 */
rustup doc --rust-by-example“5.1. Casting”
rustup doc --std 'as'
rustup doc --reference“8.2.4. Operator expressions, Type cast expressions”
// an i16 is expected when calling this function fn work(param: i16) -> i32 { // this function returns an i32 println!("param={}", param); param as i32 * 2 }
fn main() { let a = 20; // an integer... ~~> deduced to u8, from assignment to b let b: u8 = a; // u8 expected ~~> implied on a let c = 37; // an integer... ~~> deduced to i16, from function call let d = work(c); // ~~> deduced to i32, from function result // param is i16 ~~> implied on c let e = 23; // nothing implied ~~> integer is i32 by default let f = 3.4; // nothing implied ~~> floating-point is f64 by default println!("a={} b={} c={} d={} e={} f={}", a, b, c, d, e, f); } /* param=37 a=20 b=20 c=37 d=74 e=23 f=3.4 */
let () = an_expression; // this will cause an error
3 | let () = an_expression; // this will cause an error | ^^ ------------- this expression has type `u8` | | | expected `u8`, found `()`
rustup doc --rust-by-example“5.3. Inference”
rustup doc --reference“10.1.18. Inferred type”
fn main() { let iter_count = 15; print!("{} iterations:", iter_count); for i in 0..iter_count { print!(" {}", i); } println!(); } /* 15 iterations: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
fn main() { let low = 10; let high = 20; print!("high excluded:"); for i in low..high { print!(" {}", i); } println!(); print!("high included:"); for i in low..=high { // note the = symbol print!(" {}", i); } println!(); } /* high excluded: 10 11 12 13 14 15 16 17 18 19 high included: 10 11 12 13 14 15 16 17 18 19 20 */
rustup doc --book“3.5. Control Flow, Looping Through a Collection with for”
rustup doc --rust-by-example“8.4 for and range”
rustup doc --std 'for'
rustup doc --reference“8.2.13. Loop expressions, Iterator loops”
fn main() { let a = 10; let b = 20; if a < b { println!("a is less than b"); } else { println!("a is greater than or equal to b"); } } /* a is less than b */
fn main() { let a = 10; let b = 25; let twice_sum_of_a_and_b = (a + b) * 2; let twice_min_of_a_and_b = (if a < b { a } else { b }) * 2; println!( "a={} b={} twice_sum_of_a_and_b={} twice_min_of_a_and_b={}", a, b, twice_sum_of_a_and_b, twice_min_of_a_and_b ); } /* a=10 b=25 twice_sum_of_a_and_b=70 twice_min_of_a_and_b=20 */
rustup doc --book“3.5. Control Flow, if Expressions”
rustup doc --rust-by-example“8.1. if/else”
rustup doc --std 'if'
rustup doc --reference“8.2.15. If and if let expressions”
{ }) peuvent avoir une valeur si nous le souhaitons.
fn obtain_a_value() -> f64 { 12.34 }
fn transform_the_value(x: &mut f64) { *x += 9900.0088; }
fn main() { let my_var = { let mut var = obtain_a_value(); // many stages ... transform_the_value(&mut var); // ... to determine ... var // ... the value of this block }; println!("my_var={}", my_var); } /* my_var=9912.3488 */
;)✍
rustup doc --rust-by-example“7. Expressions”
rustup doc --reference“8.2.3. Block expressions”
fn main() { let a = 10; // a += 30; // error, cannot assign twice to immutable variable `a` let mut b = 25; b += 40; // correct, b is mutable println!("a={} b={}", a, b); } /* a=10 b=65 */
fn twice_plus_five(mut a: i32) -> i32 { a *= 2; // mutate a a += 5; // mutate a again a // the result of the function is the new value of a }
fn main() { for value in 10..15 { let result = twice_plus_five(value); println!("{} ~~> {}", value, result); } } /* 10 ~~> 25 11 ~~> 27 12 ~~> 29 13 ~~> 31 14 ~~> 33 */
rustup doc --book“3.1. Variables and Mutability”
rustup doc --rust-by-example“4.1. Mutability” “15.2.1. Mutability”
rustup doc --std 'mut'
rustup doc --reference“8.2. Expressions, Mutability”
fn main() { let my_tuple = (11, 22.33); println!("my_tuple contains {} and {}", my_tuple.0, my_tuple.1); } /* my_tuple contains 11 and 22.33 */
fn square_and_square_root(n: i32) -> (i32, f64) { let square = n * n; let square_root = (n as f64).sqrt(); (square, square_root) }
fn main() { let my_tuple = square_and_square_root(2); let (a, b) = my_tuple; // let a = my_tuple.0; let b = my_tuple.1; println!("a={} b={}", a, b); let (c, d) = square_and_square_root(3); println!("c={} d={}", c, d); } /* a=4 b=1.4142135623730951 c=9 d=1.7320508075688772 */
rustup doc --book“3.2. Data Types, The Tuple Type”
rustup doc --rust-by-example“2.2. Tuples”
rustup doc --std 'tuple'
rustup doc --reference“10.1.5. Tuple types” “9. Patterns, Tuple patterns”
fn integer_power( x: f64, p: i32, ) -> f64 { // this function returns an f64 if p < 0 { 1.0 / integer_power(x, -p) // x power -p is 1.0 / (x power p) } else { let mut result = 1.0; // x power 0 is 1.0 for _ in 0..p { // the value of the counter is ignored with `_` result *= x; } result } }
fn show_integer_power( x: f64, p_max: i32, ) { // this function does not return any result let (low, high) = if p_max < 0 { // ensure low is less than high (p_max, -p_max) } else { (-p_max, p_max) }; for p in low..=high { println!("{} power {} ~~> {}", x, p, integer_power(x, p)); } }
fn main() { show_integer_power(1.5, 2); show_integer_power(0.5, -3); } /* 1.5 power -2 ~~> 0.4444444444444444 1.5 power -1 ~~> 0.6666666666666666 1.5 power 0 ~~> 1 1.5 power 1 ~~> 1.5 1.5 power 2 ~~> 2.25 0.5 power -3 ~~> 8 0.5 power -2 ~~> 4 0.5 power -1 ~~> 2 0.5 power 0 ~~> 1 0.5 power 1 ~~> 0.5 0.5 power 2 ~~> 0.25 0.5 power 3 ~~> 0.125 */
rustup doc --book“3.3. Functions”
rustup doc --rust-by-example“9. Functions”
rustup doc --std 'fn'
rustup doc --reference“6.4. Functions”
std::option::Option<T>qui est si souvent utile que le langage le rend directement accessible par le nom
Option<T>✍
fn main() { let v = vec![1.1, 2.2, 3.3]; for idx in [2, 0, 3, 1] { let elem = v.get(idx); // returns an Option match elem { Some(value) => { println!("value {} at index {}", value, idx); } None => { println!("nothing at index {}", idx); } } } } /* value 3.3 at index 2 value 1.1 at index 0 nothing at index 3 value 2.2 at index 1 */
fn main() { let v = vec![1.1, 2.2, 3.3]; for idx in [2, 0, 3, 1] { if let Some(value) = v.get(idx) { println!("value {} at index {}", value, idx); } else { // this `else` branch is optional println!("nothing at index {}", idx); } } } /* value 3.3 at index 2 value 1.1 at index 0 nothing at index 3 value 2.2 at index 1 */
fn main() { let v = vec![1.1, 2.2, 3.3]; for idx in [2, 0, 3, 1] { let value = v.get(idx).unwrap(); // assuming it's not None println!("value {} at index {}", value, idx); } } /* value 3.3 at index 2 value 1.1 at index 0 thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:4:32 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace */
fn square_if_odd(n: i32) -> Option<i32> { if n % 2 == 0 { None // n is even ~~> the option will contain nothing } else { Some(n * n) // n is odd ~~> the option will contain something } }
fn main() { for n in [2, 5, -4, -3] { println!("{} ~~> {:?}", n, square_if_odd(n)); } } /* 2 ~~> None 5 ~~> Some(25) -4 ~~> None -3 ~~> Some(9) */
rustup doc --book“6.1. Defining an Enum, The Option Enum and Its Advantages Over Null Values”
rustup doc --book“6.2. The match Control Flow Construct, Matching with Option
rustup doc --rust-by-example“19.4. Option” “18.3. Option & unwrap” “18.3.1. Unpacking options with ?”
rustup doc --std 'std::option'
std::result::Result<T, E>qui est si souvent utile que le langage le rend directement accessible par le nom
Result<T, E>✍
fn main() { for txt in ["123", "what?", "456"] { let converted = txt.parse::<u8>(); match converted { Ok(value) => { println!("u8 with value {} obtained from {:?}", value, txt); } Err(e) => { println!("cannot obtain an u8 from {:?}: {}", txt, e); } } } } /* u8 with value 123 obtained from "123" cannot obtain an u8 from "what?": invalid digit found in string cannot obtain an u8 from "456": number too large to fit in target type */
fn main() { for txt in ["123", "what?", "456"] { if let Ok(value) = txt.parse::<u8>() { println!("u8 with value {} obtained from {:?}", value, txt); } else { // this `else` branch is optional println!("cannot obtain an u8 from {:?}", txt); } } } /* u8 with value 123 obtained from "123" cannot obtain an u8 from "what?" cannot obtain an u8 from "456" */
fn add_as_real_values( txt_a: &str, txt_b: &str, ) -> Result<f64, Box<dyn std::error::Error>> { let a = txt_a.parse::<f64>()?; // ? ~~> might return an error let b = txt_b.parse::<f64>()?; // ? ~~> might return an error println!("got {} and {}", a, b); // for v in [a, b] { // if v < 0.0 { // Err(format!("unexpected negative value: {}", v))?; // } // } Ok(a + b) // provides the actual f64 result, no error to be reported }
fn main() -> Result<(), Box<dyn std::error::Error>> { for (a, b) in [("1.2", "4.5"), ("8.6", "-6.4"), ("9.8", "no!")] { let sum = add_as_real_values(a, b)?; // ? ~~> might return an error println!("~~> {}", sum); } println!("done"); Ok(()) // provides the actual () result, no error to be reported } /* got 1.2 and 4.5 ~~> 5.7 got 8.6 and -6.4 ~~> 2.1999999999999993 Error: ParseFloatError { kind: Invalid } */
-> f64, mais par
-> Result<f64, ... >,
-> ()(ou simplement rien du tout), mais par
-> Result<(), ... >,
Box<dyn std::error::Error>✍
fn main() { for txt in ["123", "what?", "456"] { let value = txt.parse::<u8>().unwrap(); // assuming it's not Err println!("u8 with value {} obtained from {:?}", value, txt); } } /* u8 with value 123 obtained from "123" thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }', src/main.rs:3:39 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace */
fn inv_square(x: f32) -> Result<f32, Box<dyn std::error::Error>> { let square = x * x; if square < f32::EPSILON { let msg = format!("{} is too near from zero", x); Err(msg)?; } Ok(1.0 / square) }
fn main() { for n in [1.2, f32::EPSILON, -2.3, 0.0] { println!("{} ~~> {:?}", n, inv_square(n)); } } /* 1.2 ~~> Ok(0.6944444) 0.00000011920929 ~~> Err("0.00000011920929 is too near from zero") -2.3 ~~> Ok(0.18903592) 0 ~~> Err("0 is too near from zero") */
rustup doc --book“9.2. Recoverable Errors with Result”
rustup doc --book“9.2. Recoverable Errors with Result, Propagating Errors”
rustup doc --book“9.2. Recoverable Errors with Result, Where The ? Operator Can Be Used”
rustup doc --book“6.2. The match Control Flow Construct, Matching with Option
rustup doc --rust-by-example“18.4. Result” “18.4.4. Introducing ?” “18.5.3. Boxing errors”
rustup doc --std 'std::result'