Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
463 views
in Technique[技术] by (71.8m points)

rust - Trying to do a mutable borrow of members of a Vec() but rustc thinks I'm trying to mutable borrow the Vec()

In the assembler I'm working on, identifiers can be of two types - labels or symbols. When being defined, the tokenize_line() helper function can automatically set the identifier type argument of the Identifier variant of the TokenInfo enum to Some(IdentifierType::Label) or Some(IdentifierType::Symbol). However, when an identifier is being used the identifier type is not immediately obvious as it is when defining identifiers.

As such, this needs to be done in the main lex() function. However, in order to do this, I need to grab mutable borrows of all the identifier tokens because unless the identifier type is already Some(whatever) I will have to modify them. Part of this was doing a linear search through my vector of vectors of tokens (list of list of tokens) and grabbing the positions of all identifier tokens and the second part is actually making mutable borrows of all those identifier tokens and putting those into a vector/list.

However, doing this through a for loop creates a problem: the rust compiler thinks I'm repeatedly borrowing the vector/list, and not the individual tokens. I have no idea if this can be worked around, or if I'll just have to use the position list and the actual list of lists of tokens. Here's my code:

let mut i = 0; // i = Line counter
let mut j = 0; // j = Token counter
let mut positions: Vec<(usize, usize)> = vec!();
for line in &tokens {
    for token in line {
        match &token.info {
            TokenInfo::Identifier(t) => {
                positions.push((i, j));
            }
            _ => {}
        }
        j = j + 1;
    }
    i = i + 1;
}

let mut ident_tokens: Vec<&mut Token> = vec!();

for position in positions {
    ident_tokens.push(&mut tokens[position.0][position.1]);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The reference returned by the [] syntax is considered to be derived from the reference to the container, so you can't have two such references at the same time. Therefore, instead of

fn vec_of_ref_mut(vec: &mut Vec<i32>) -> Vec<&mut i32> {
    let mut result = vec![];
    
    for i in 0..vec.len() {
        result.push(&mut vec[i]);
    }
    
    result
}

you would need to use iter_mut:

fn vec_of_ref_mut(vec: &mut Vec<i32>) -> Vec<&mut i32> {
    vec.iter_mut().collect()
}

In a nested case like yours, you would need to use flat_map. For example:

fn vec_of_ref_mut(vec: &mut Vec<Vec<i32>>) -> Vec<&mut i32> {
    vec.iter_mut().flat_map(|sub_vec| sub_vec.iter_mut()).collect()
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...