Loading rust_05_sequences...
rustup doc --std 'std::collections'.
fn main() { let mut a1 = [1.1, 2.2, 3.3, 4.4, 5.5]; // five values a1[2] += 90.09; // mutate an element println!("a1 contains {} elements: {:?}", a1.len(), a1); let mut a2 = [99_u16; 8]; // 8 identical values a2[5] *= 100; // mutate an element println!("a2 contains {} elements: {:?}", a2.len(), a2); } /* a1 contains 5 elements: [1.1, 2.2, 93.39, 4.4, 5.5] a2 contains 8 elements: [99, 99, 99, 99, 99, 9900, 99, 99] */
rustup doc --book“3.2. Data Types, The Array Type”
rustup doc --rust-by-example“2.3. Arrays and Slices”
rustup doc --std 'array'
rustup doc --reference“10.1.6. Array types”
fn main() { let mut v = Vec::new(); if v.is_empty() { println!("v is initially empty"); } v.push(1.2); // insert ... v.push(3.4); // ... some ... v.push(5.6); // ... f64 ... v.push(7.8); // ... values v[2] += 90.09; // mutate an element println!("now, v contains {} elements: {:?}", v.len(), v); v.remove(1); // v[1] disappears, v[2] and v[3] are moved down println!("and then, v contains {} elements: {:?}", v.len(), v); } /* v is initially empty now, v contains 4 elements: [1.2, 3.4, 95.69, 7.8] and then, v contains 3 elements: [1.2, 95.69, 7.8] */
std::vec::Vec<T>, ou simplement
Vec<T>, avec T indiquant un type de notre choix.
let mut v: Vec<f64> = Vec::new();ou encore
let mut v = Vec::<f64>::new();, mais, puisque le langage permet la déduction automatique des types, il est rare que nous ayons besoin de donner autant de détails. Vous trouverez certainement dans d'autres exemples l'initialisation de vectors sous une forme qui rappelle l'initialisation des tableaux✍
rustup doc --book“8.1. Storing Lists of Values with Vectors”
rustup doc --rust-by-example“19.2. Vectors”
rustup doc --std 'std::vec'
rustup doc --std 'std::collections'.
fn main() { let prepared = vec![11, 22, 33, 44, 55]; let mut kept = Vec::new(); println!("before: prepared={:?} kept={:?}", prepared, kept); for elem in prepared.into_iter() { // .into_iter() ~~> consume if elem % 2 == 1 { kept.push(elem); // consider only odd integers } } // println!("after: prepared={:?}", prepared); // error, value borrowed here after move println!("after: kept={:?}", kept); } /* before: prepared=[11, 22, 33, 44, 55] kept=[] after: kept=[11, 33, 55] */
fn main() { let v = vec![1.1, 2.2, 3.3, 4.4, 5.5]; println!("before: v={:?}", v); let mut square_sum = 0.0; for ref_to_elem in v.iter() { // .iter() ~~> iterate as non-mutable let value = *ref_to_elem; // consult this element square_sum += value * value; } println!("square_sum={}", square_sum); println!("after: v={:?}", v); } /* before: v=[1.1, 2.2, 3.3, 4.4, 5.5] square_sum=66.55 after: v=[1.1, 2.2, 3.3, 4.4, 5.5] */
fn main() { let mut v = vec![1.1, 2.2, 3.3, 4.4, 5.5]; println!("before: v={:?}", v); let mut idx = 0; for ref_to_elem in v.iter_mut() { // .iter_mut() ~~> iterate as mutable let factor = if idx % 2 == 1 { 0.5 } else { -0.5 }; idx += 1; *ref_to_elem *= factor; // mutate this element } println!("after: v={:?}", v); } /* before: v=[1.1, 2.2, 3.3, 4.4, 5.5] after: v=[-0.55, 1.1, -1.65, 2.2, -2.75] */
fn main() { let mut v = vec![1.1, 2.2, 3.3, 4.4, 5.5]; println!("before: v={:?}", v); for (idx, ref_to_elem) in v.iter_mut().enumerate() { // .iter_mut() ~~> iterate as mutable let factor = if idx % 2 == 1 { 0.5 } else { -0.5 }; *ref_to_elem *= factor; // mutate this element } println!("after: v={:?}", v); } /* before: v=[1.1, 2.2, 3.3, 4.4, 5.5] after: v=[-0.55, 1.1, -1.65, 2.2, -2.75] */
for elem in sequence { ... }
rustup doc --rust-by-example“8.4. for and range, for and iterators”
rustup doc --std 'std::iter'
fn main() { let mut elements = vec![11, 22, 33, 44, 55]; println!("before: elements={:?}", elements); elements.retain(|ref_to_elem| { let value = *ref_to_elem; // consult this element value % 2 == 1 // consider only odd integers }); println!("after: elements={:?}", elements); } /* before: elements=[11, 22, 33, 44, 55] after: elements=[11, 33, 55] */
fn main() { let prepared = vec![11, 22, 33, 44, 55]; println!("before: prepared={:?}", prepared); let kept = Vec::from_iter(prepared.into_iter().filter(|ref_to_elem| { let value = *ref_to_elem; // consult this element value % 2 == 1 // consider only odd integers })); println!("after: kept={:?}", kept); } /* before: prepared=[11, 22, 33, 44, 55] after: kept=[11, 33, 55] */
fn main() { let v = vec![1.1, 2.2, 3.3, 4.4, 5.5]; println!("before: v={:?}", v); let square_sum = v .iter() .map(|ref_to_elem| { let value = *ref_to_elem; // consult this element value * value // emit its square }) .sum::<f64>(); println!("square_sum={}", square_sum); println!("after: v={:?}", v); } /* before: v=[1.1, 2.2, 3.3, 4.4, 5.5] square_sum=66.55 after: v=[1.1, 2.2, 3.3, 4.4, 5.5] */
fn main() { let mut va = vec![1.1, 2.2, 3.3, 4.4, 5.5]; let vb = vec![2.5, 0.5, 0.25, 1.25, 0.75]; println!("before: va={:?} vb={:?}", va, vb); for (ref_to_a, ref_to_b) in va.iter_mut().zip(vb.iter()) { // .iter_mut() ~~> iterate va as mutable // .iter() ~~> iterate vb as non-mutable let a = *ref_to_a; let b = *ref_to_b; let value = a * b; *ref_to_a = value; // mutate this element } println!("after: va={:?} vb={:?}", va, vb); } /* before: va=[1.1, 2.2, 3.3, 4.4, 5.5] vb=[2.5, 0.5, 0.25, 1.25, 0.75] after: va=[2.75, 1.1, 0.825, 5.5, 4.125] vb=[2.5, 0.5, 0.25, 1.25, 0.75] */
fn main() { let mut va = vec![1.1, 2.2, 3.3, 4.4, 5.5]; let vb = vec![2.5, 0.5, 0.25, 1.25, 0.75]; println!("before: va={:?} vb={:?}", va, vb); let square_sum = va .iter_mut() // .iter_mut() ~~> iterate va as mutable .zip(vb.iter()) // .iter() ~~> iterate vb as non-mutable .map(|(ref_to_a, ref_to_b)| { let a = *ref_to_a; let b = *ref_to_b; let value = a * b; *ref_to_a = value; // mutate this element value * value // emit its square }) .sum::<f64>(); println!("square_sum={}", square_sum); println!("after: va={:?} vb={:?}", va, vb); } /* before: va=[1.1, 2.2, 3.3, 4.4, 5.5] vb=[2.5, 0.5, 0.25, 1.25, 0.75] square_sum=56.71875 after: va=[2.75, 1.1, 0.825, 5.5, 4.125] vb=[2.5, 0.5, 0.25, 1.25, 0.75] */
print!("rev:"); let values = vec![10, 20, 30, 40]; for ref_to_elem in values.iter().rev() { print!(" {:?}", ref_to_elem); } println!(); // rev: 40 30 20 10
print!("chain:"); let values1 = vec![10, 20, 30, 40]; let values2 = vec![77, 88, 99]; for ref_to_elem in values1.iter().chain(values2.iter()) { print!(" {:?}", ref_to_elem); } println!(); // chain: 10 20 30 40 77 88 99
print!("filter_map:"); let values = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; for value in values.iter().filter_map(|ref_to_elem| { // detect if element is even or odd if *ref_to_elem % 2 == 0 { None // ignore even elements } else { Some(*ref_to_elem * 2) // emit twice odd elements } }) { print!(" {:?}", value); } println!(); // filter_map: 2 6 10 14 18
let values = vec!["57", "3", "72", "158"]; let min_str = values.iter().min(); println!("min_str: {:?}", min_str); // min_str: Some("158") let max_str = values.iter().max(); println!("max_str: {:?}", max_str); // max_str: Some("72")
let values = vec!["57", "3", "72", "158"]; let min_as_int = values.iter().min_by_key(|ref_to_ref_to_elem| { // consider element as an integer value ref_to_ref_to_elem.parse::<i32>().unwrap() }); println!("min_as_int: {:?}", min_as_int); // min_as_int: Some("3") let max_as_int = values.iter().max_by_key(|ref_to_ref_to_elem| { // consider element as an integer value ref_to_ref_to_elem.parse::<i32>().unwrap() }); println!("max_as_int: {:?}", max_as_int); // max_as_int: Some("158")
let values = vec![10, 20, 30, 40]; let result = values.iter().fold(0, |accum, ref_to_elem| { // combine each element with the accumulator in order // to determine the next value of the accumulator accum + *ref_to_elem * 2 }); println!("fold: {:?}", result); // fold: 200
let values = vec![1, 3, 5, 7, 9]; let r1 = values.iter().all(|ref_to_elem| { // detect if element is odd *ref_to_elem % 2 == 1 }); println!("all odd: {:?}", r1); // all odd: true let r2 = values.iter().any(|ref_to_elem| { // detect if element is even *ref_to_elem % 2 == 0 }); println!("any even: {:?}", r2); // any even: false let r3 = values.iter().all(|ref_to_elem| { // detect if element is multiple of three *ref_to_elem % 3 == 0 }); println!("all multiple of three: {:?}", r3); // all multiple of three: false let r4 = values.iter().any(|ref_to_elem| { // detect if element is multiple of three *ref_to_elem % 3 == 0 }); println!("any multiple of three: {:?}", r4); // any multiple of three: true
rustup doc --book“13.2. Processing a Series of Items with Iterators”
rustup doc --book“13.4. Comparing Performance: Loops vs. Iterators”.
rustup doc --rust-by-example“8.4. for and range, for and iterators”
rustup doc --std 'std::iter::Iterator'
rustup doc --std 'std::iter::Filter',
rustup doc --std 'std::iter::Map',
rustup doc --std 'std::iter::Sum',
rustup doc --std 'std::iter::Enumerate',
rustup doc --std 'std::iter::Zip',
rustup doc --std 'std::iter::Rev',
rustup doc --std 'std::iter::Chain',
rustup doc --std 'std::iter::FilterMap'
fn main() { let v = vec![11, 22, 33, 44, 55, 66]; let optional_ref_to_found = v.iter().find(|ref_to_ref_to_elem| { // test if this element is a multiple of three **ref_to_ref_to_elem % 3 == 0 }); if let Some(ref_to_found) = optional_ref_to_found { println!("found a multiple of three: {}", *ref_to_found); } } /* found a multiple of three: 33 */
fn main() { let optional_found = (1..=100).rev().find(|ref_to_value| { // test if this value is a multiple of thirteen *ref_to_value % 13 == 0 }); if let Some(found) = optional_found { println!("found last multiple of thirteen: {}", found); } } /* found last multiple of thirteen: 91 */
fn main() { let mut v = vec![11, 22, 33, 44, 55, 66]; println!("before: v={:?}", v); let optional_ref_to_found = v.iter_mut().find(|ref_to_ref_to_elem| { // test if this element is a multiple of three **ref_to_ref_to_elem % 3 == 0 }); if let Some(ref_to_found) = optional_ref_to_found { *ref_to_found += 9900; // mutate the multiple of three } println!("after: v={:?}", v); } /* before: v=[11, 22, 33, 44, 55, 66] after: v=[11, 22, 9933, 44, 55, 66] */
fn main() { let mut v = vec![11, 22, 33, 44, 55, 66]; println!("before: v={:?}", v); let optional_idx = v.iter().position(|ref_to_elem| { // test if this element is a multiple of three *ref_to_elem % 3 == 0 }); if let Some(idx) = optional_idx { println!("changing multiple of three at index {}", idx); v[idx] += 9900; } println!("after: v={:?}", v); } /* before: v=[11, 22, 33, 44, 55, 66] changing multiple of three at index 2 after: v=[11, 22, 9933, 44, 55, 66] */
rustup doc --rust-by-example“9.2.6.2. Searching through iterators”
rustup doc --std 'std::iter::Iterator'
fn array_of_six_magnitude(elements: &[f64; 6]) -> f64 { elements.iter().map(|e| *e * *e).sum::<f64>().sqrt() }
fn vector_magnitude(elements: &Vec<f64>) -> f64 { elements.iter().map(|e| *e * *e).sum::<f64>().sqrt() }
fn slice_magnitude(elements: &[f64]) -> f64 { elements.iter().map(|e| *e * *e).sum::<f64>().sqrt() }
fn slice_normalise(elements: &mut [f64]) { let factor = 1.0 / slice_magnitude(elements); for e in elements.iter_mut() { *e *= factor; } }
fn main() { let mut a = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6]; let m1 = array_of_six_magnitude(&a); // let m2 = vector_magnitude(&a); // error, expected struct `Vec`, found array `[f64; 6]` let m3 = slice_magnitude(&a); slice_normalise(&mut a); println!("a: {} {} ~~> {}", m1, m3, slice_magnitude(&a)); // let mut v = vec![1.1, 2.2, 3.3, 4.4, 5.5, 6.6]; // let m4 = array_of_six_magnitude(&v); // error, expected array `[f64; 6]`, found struct `Vec` let m5 = vector_magnitude(&v); let m6 = slice_magnitude(v.as_slice()); slice_normalise(v.as_mut_slice()); println!("v: {} {} ~~> {}", m5, m6, slice_magnitude(v.as_slice())); } /* a: 10.493331215586402 10.493331215586402 ~~> 1 v: 10.493331215586402 10.493331215586402 ~~> 1 */
fn main() { let mut v = Vec::from_iter(0..12); println!("before: v={:?}", v); let s1 = &mut v[2..10]; // s1 is a sub-slice of v for elem in s1.iter_mut() { // work on slice s1 *elem += 900; } println!("s1={:?}", s1); let s2 = &mut s1[2..6]; // s2 is a sub-slice of s1 for elem in s2.iter_mut() { // work on slice s2 *elem += 8000; } println!("s2={:?}", s2); println!("after: v={:?}", v); } /* before: v=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] s1=[902, 903, 904, 905, 906, 907, 908, 909] s2=[8904, 8905, 8906, 8907] after: v=[0, 1, 902, 903, 8904, 8905, 8906, 8907, 908, 909, 10, 11] */
rustup doc --book“4.3. The Slice Type, Other Slices”
rustup doc --rust-by-example“2.3. Arrays and Slices”
rustup doc --std 'std::slice'
rustup doc --reference“10.1.7. Slice types”
fn main() { for txt in ["sur", "sûr"] { println!("text {:?} has length {}", txt, txt.len()); print!(" chars:"); for c in txt.chars() { print!(" {:?}", c); } println!(); print!(" bytes:"); for b in txt.as_bytes().iter() { print!(" {}", b); } println!(); } } /* text "sur" has length 3 chars: 's' 'u' 'r' bytes: 115 117 114 text "sûr" has length 4 chars: 's' 'û' 'r' bytes: 115 195 187 114 */
&str, qui est habituellement nommé string-slice : il s'agit bien d'une slice mais qui fait référence à une séquence contiguë de bytes stockés quelque part.
&[u8]car les bytes qui la constituent doivent nécessairement former une séquence de caractères UTF-8 valide✍
&strn'assurait pas automatiquement de telles garanties.
fn count_chars(txt: &str) -> usize { txt.chars().count() }
fn count_letters(txt: &str) -> usize { txt.chars().filter(|c| c.is_alphabetic()).count() }
fn append_sentence( txt: &mut String, sentence: &str, max_width: usize, ) { if let Some(last_line) = txt.split('\n').last() { if !last_line.is_empty() { let new_width = count_chars(last_line) + count_chars(sentence); let separator = if new_width < max_width { ' ' } else { '\n' }; txt.push(separator); // append suitable separator if needed } } txt.push_str(sentence); // append sentence in any case }
fn main() { let mut my_text = "Êtes-vous sûrs d'avoir bien étudié ?".to_owned(); let chars = count_chars(my_text.as_str()); let letters = count_letters(my_text.as_str()); let str1 = format!("The initial content was {} characters long", chars); let str2 = format!("but had only {} letters", letters); let max_width = 70; append_sentence(&mut my_text, &str1, max_width); append_sentence(&mut my_text, &str2, max_width); println!("{}{}", "~".repeat(max_width), max_width); println!("{}", my_text); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~70 Êtes-vous sûrs d'avoir bien étudié ? The initial content was 36 characters long but had only 28 letters */
let s = String::from("my text");.
let mut s = String::new();pour une chaîne vide qui sera complétée ultérieurement.
rustup doc --book“8.2. Storing UTF-8 Encoded Text with Strings”
rustup doc --book“4.3. The Slice Type”
rustup doc --book“4.1. What is Ownership?”
rustup doc --rust-by-example“19.3. Strings”
rustup doc --std 'std::string'
rustup doc --reference“2.6. Tokens, Character and string literals”