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 'f32',
rustup doc 'f64'
rustup doc 'u8',
rustup doc 'i8'
rustup doc 'u16',
rustup doc 'i16'
rustup doc 'u32',
rustup doc 'i32'
rustup doc 'u64',
rustup doc 'i64'
rustup doc 'u128',
rustup doc 'i128'
rustup doc 'usize',
rustup doc '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::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 '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 '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 '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 '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 '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 '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::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::result'