Loading rust_04_values...
def remove_unexpected_element(sequence, unexpected): for (index, elem) in enumerate(sequence): if elem == unexpected: sequence.pop(index)
seq = [10, 10, 20, 20, 30, 30] remove_unexpected_element(seq, 20) print(seq) # [10, 10, 20, 30, 30]
fn use_integer(param: i32) { println!("in use_integer(), param={:?}", param); }
fn main() { let var1 = 123; let var2 = var1; // the value in var1 is COPIED into var2 use_integer(var1); // the value in var1 is COPIED into param use_integer(var2); // the value in var2 is COPIED into param println!("var1={:?}", var1); println!("var2={:?}", var2); } /* in use_integer(), param=123 in use_integer(), param=123 var1=123 var2=123 */
fn use_vector(param: Vec<i32>) { println!("in use_vector(), param={:?}", param); }
fn main() { let var1 = vec![1, 2, 3]; let var2 = var1; // the value in var1 is MOVED into var2 // use_vector(var1); // error, value borrowed here after move use_vector(var2); // the value in var2 is MOVED into param // println!("var1={:?}", var1); // error, value borrowed here after move // println!("var2={:?}", var2); // error, value borrowed here after move } /* in use_vector(), param=[1, 2, 3] */
fn use_vector(param: Vec<i32>) { println!("in use_vector(), param={:?}", param); }
fn main() { let var1 = vec![1, 2, 3]; let var2 = var1.clone(); // a CLONE of var1 is made, then MOVED into var2 use_vector(var1.clone()); // a CLONE of var1 is made, then MOVED into param use_vector(var2.clone()); // a CLONE of var2 is made, then MOVED into param println!("var1={:?}", var1); println!("var2={:?}", var2); } /* in use_vector(), param=[1, 2, 3] in use_vector(), param=[1, 2, 3] var1=[1, 2, 3] var2=[1, 2, 3] */
rustup doc --book“4.1. What is Ownership?”
rustup doc --book“4.1. What is Ownership?, Ways Variables and Data Interact: Move”
rustup doc --book“4.1. What is Ownership?, Ways Variables and Data Interact: Clone”
rustup doc --rust-by-example“15.1. RAII” “15.2. Ownership and moves”
rustup doc --std 'std::clone',
rustup doc --std 'std::marker::Copy'
fn use_vector(param: &Vec<i32>) { // a SHARED-REFERENCE to a vector is expected println!("in use_vector(), param={:?}", param); }
fn main() { let var1 = vec![1, 2, 3]; let var2 = &var1; // var2 is a SHARED-REFERENCE to the vector in var1 use_vector(&var1); // a SHARED-REFERENCE to the vector is passed use_vector(var2); // a SHARED-REFERENCE to the vector is passed println!("var1={:?}", var1); println!("var2={:?}", var2); } /* in use_vector(), param=[1, 2, 3] in use_vector(), param=[1, 2, 3] var1=[1, 2, 3] var2=[1, 2, 3] */
&Vec<i32>,
let mut my_ref = &my_first_data; // ... use my_ref to access my_first_data ... my_ref = &my_second_data; // mutate the SHARED-REFERENCE itself, not the data // ... use my_ref to access my_second_data ...
rustup doc --book“4.2. References and Borrowing”
rustup doc --rust-by-example“15.3. Borrowing”
rustup doc --reference“10.1.13. Pointer types, Shared references (&)”
fn use_vector(param: &mut Vec<i32>) { // an EXCLUSIVE-REFERENCE to a vector is expected println!("in use_vector(), param={:?}", param); param.push(8); // mutate the vector }
fn main() { let mut var1 = vec![1, 2, 3]; use_vector(&mut var1); // an EXCLUSIVE-REFERENCE to the vector is passed // ~~~ exclusive borrow of var1 by var2 starts here ~~~ let var2 = &mut var1; // var2 is an EXCLUSIVE REFERENCE to the vector in var1 var2.push(9); // mutate the vector use_vector(var2); // an EXCLUSIVE-REFERENCE to the vector is passed println!("var2={:?}", var2); // ~~~ exclusive borrow of var1 by var2 stops here ~~~ println!("var1={:?}", var1); } /* in use_vector(), param=[1, 2, 3] in use_vector(), param=[1, 2, 3, 8, 9] var2=[1, 2, 3, 8, 9, 8] var1=[1, 2, 3, 8, 9, 8] */
&mut Vec<i32>, permettent bien la modification du vector possédé par la variable var1 (nécessairement qualifiée avec mut). Les références utilisées ici sont dites exclusives car, tant que l'une d'elles existe, elle doit être la seule référence à pouvoir exploiter la donnée désignée.
rustup doc --book“4.2. References and Borrowing, Mutable References”
rustup doc --book“4.2. References and Borrowing, The Rules of References”
rustup doc --rust-by-example“15.3.1. Mutability”
rustup doc --reference“10.1.13. Pointer types, Mutable references (&mut)”
&mut [Element]pour le paramètre, et non un vector
&mut Vec<Element>qui aurait pu également convenir.
struct Element { value: f64, next_value: Option<f64>, }
fn adjust_next_values(elements: &mut [Element]) { for elem in elements.iter_mut() { // .iter_mut() ~~> iterate as mutable // !!! error, cannot borrow `*elements` as immutable // !!! because it is also borrowed as mutable for other in elements.iter() { // .iter() ~~> iterate as non-mutable if !std::ptr::eq(other, elem) { // avoid self interaction // ... now we can update elem depending upon other ... if other.value > elem.value { let update_next = if let Some(next_value) = elem.next_value { other.value < next_value } else { true }; if update_next { elem.next_value = Some(other.value); } } } } } }
fn main() { let mut elements = Vec::from_iter( [2.3, 7.5, 4.4, 1.8, 6.7] .into_iter() // consume these arbitrary values .map(|value| Element { // produce an Element for each of them value, next_value: None, }), ); // make a vector with these Elements adjust_next_values(&mut elements); for e in elements.iter() { println!("{} ~~> {:?}", e.value, e.next_value); } } /* !!! this example is rejected by the compiler !!! */
use std::cell::RefCell;
struct Element { value: f64, next_value: Option<f64>, }
fn adjust_next_values(elements: &[RefCell<Element>]) { for elem_cell in elements.iter() { // .iter() ~~> iterate as non-mutable let mut elem = elem_cell.borrow_mut(); // however, we obtain a mutable access to this element for other_cell in elements.iter() { // .iter() ~~> iterate as non-mutable (again!) if !std::ptr::eq(other_cell, elem_cell) { // avoid self interaction let other = other_cell.borrow(); // obtain an immutable access to this other element // ... now we can update elem depending upon other ... if other.value > elem.value { let update_next = if let Some(next_value) = elem.next_value { other.value < next_value } else { true }; if update_next { elem.next_value = Some(other.value); } } } } } }
fn main() { let elements = Vec::from_iter( [2.3, 7.5, 4.4, 1.8, 6.7] .into_iter() // consume these arbitrary values .map(|value| { RefCell::new(Element { // produce an Element for each of them value, // (embedded in a RefCell) next_value: None, }) }), ); // make a vector with these Elements adjust_next_values(&elements); for rc in elements.iter() { let e = rc.borrow(); println!("{} ~~> {:?}", e.value, e.next_value); } } /* 2.3 ~~> Some(4.4) 7.5 ~~> None 4.4 ~~> Some(6.7) 1.8 ~~> Some(2.3) 6.7 ~~> Some(7.5) */
RefCell<Element>.
rustup doc --book“15.5. RefCell<T> and the Interior Mutability Pattern”
rustup doc --std 'std::cell'
rustup doc --reference“10.4. Interior mutability”