Location>code7788 >text

Rust's Reborrow Mechanism

Popularity:502 ℃/2024-10-27 12:15:02

Recently, the use ofRustluckilyReborrowconcepts, recorded for future reference.

1. Causes

Cause prepares the data forMin-MaxNormalized processing, that is, mapping a range of data to a new range.

First, the data needs to be traversed to find out where themaximum valuescap (a poem)minimum value, and then change the values of the original data set by using the formula.

Min-MaxFormula: Normalized value = (original value - minimum value) / (maximum value - minimum value)

The simplified code is as follows:

fn main() {
    let mut values = vec![10.5, 22.3, 103.5, 45.75];
    let v = &mut values;
    println!("raw data: {:#?}", v);

    let mut max = f64::MIN;
    let mut min = f64::MAX;

    for n in v {
        if *n > max {
            max = *n;
        }
        if *n < min {
            min = *n;
        }
    }

    println!("max is {}", max);
    println!("min is {}", min);

    println!("commencementMin-MaxStandardized processing...");
    for n in v {
        *n = (*n - min) / (max - min);
    }

    println!("Post-processed data: {:#?}", values);
}

It runs with the following error:

error[E0382]: use of moved value: `v`                                                                     
   --> src/:22:14
    |
3   |     let v = &mut values;
    |         - move occurs because `v` has type `&mut Vec<f64>`, which does not implement the `Copy` trai
t
...
9   |     for n in v {
    |              - `v` moved due to this implicit call to `.into_iter()`
...
22  |     for n in v {
    |              ^ value used here after move
    |

probablyLine 9(math.) ergodicvof finding the maximum and minimum values whenVariable borrowing vthat the right to use it has been transferred.

thus inLine 22miss (feel wistful about the absence of sb. or sth)Iterate over v againError when going to change the value.

Here, becauseVectorNot realizedCopy Trait, so it's mutable borrowing on the first traversal due to an implicit call to the.into_iter(), ownership is transferred.

If you want to traverse theVector, you can use its immutable borrowing, such as defining thelet v = &values;

Then it is possible to traverse multiple timesvBecause of the immutable borrowing are realizedCopy Trait

But the second time I traversedvwhen it is used, it is also necessary to modify the value in it, so it must be defined as a variable borrowinglet v = &mut values;

By searching for information, it was found thatReborrowmechanism can fulfill the above requirements.

2. The concept of reborrow

Borrowing (Borrow) isRustIt is an important concept in the concept of a mechanism that allows code to access a value without taking ownership of it.

(indicates contrast)Reborrowthen the creation of a new borrowing based on a pre-existing borrowing.

This new borrowing can be immutable or mutable (provided that the original borrowing is mutable and no other borrowing exists).

Overall.ReborrowExtend the lifecycle of references and securely access values in a wider scope by creating new borrows on top of existing ones.

3. Solutions

The following is a practical test for theReborrowConceptual understanding.

Returning to the problem encountered in the first section, the solution is to traverse the first time thevTime (Line 9), don't transfer ownership.

Thus, the second traversal ofvLine 22) would not have reported the"value used here after move"The error.

according toReborrowThe mechanism that we have inLine 9canReborrowVariable borrowingvThe transfer was made in such a way that it was re-borrowed.vInstead ofvitself.

The method of change is simple.Line 9change intofor n in &*v {That's all, that is, firstReduction v(*v), and thenReborrow(&*v)。

Modify and run the code again:

$ cargo run

Raw data: [
    10.5,
    22.3,
    10.5, 22.3, 103.5,
    45.75.
max is 103.5]
max is 103.5
min is 10.5
Start Min-Max normalization...
Processed data: [
    0.0,
    0.12688172043010754, [
    1.0, 0.379032258080754
    0.3790322580645161, ]
]

valuesThe data in the

Note that this is where thevReborrow into an immutable borrowing&*vBecause I didn't need to change it the first time I traversed it.v

if you want tovReborrow into a variable borrowing can be written as:&mut *v