代码之家  ›  专栏  ›  技术社区  ›  sudoExclamationExclamation

Rust错误:一次不能多次借用为可变,不能借用为不可变,因为它也被借用为可变

  •  0
  • sudoExclamationExclamation  · 技术社区  · 1 月前

    我有以下示例代码:

    let mut errors: Vec<String> = Vec::new();
    
    let msg1 = "message 1".to_string();
    let msg2 = "message 2".to_string();
    let msg3 = "message 3".to_string();
    
    let mut push_auth_requirements = || {
        errors.push(msg1.clone());
        errors.push(msg2.clone());
    };
    
    let mut push_auth_error = || {
        errors.push(msg3.clone());
        push_auth_requirements();
    };
    
    // do some stuff
    
    if errors.is_empty() {
        // do more stuff
        if "bob" == "dsadasd" {
            push_auth_requirements();
        } else {
            push_auth_error();
        }
    }
    
    println!("Errors: {:?}",errors);
    

    这会导致两个错误:

    error[E0499]: cannot borrow `errors` as mutable more than once at a time
      --> src/main.rs:89:31
       |
    84 |     let mut push_auth_requirements = || {
       |                                      -- first mutable borrow occurs here
    85 |         errors.push(msg1.clone());
       |         ------ first borrow occurs due to use of `errors` in closure
    ...
    89 |     let mut push_auth_error = || {
       |                               ^^ second mutable borrow occurs here
    90 |         errors.push(msg3.clone());
       |         ------ second borrow occurs due to use of `errors` in closure
    91 |         push_auth_requirements();
       |         ---------------------- first borrow later captured here by closure
    
    error[E0502]: cannot borrow `errors` as immutable because it is also borrowed as mutable
      --> src/main.rs:96:8
       |
    84 |     let mut push_auth_requirements = || {
       |                                      -- mutable borrow occurs here
    85 |         errors.push(msg1.clone());
       |         ------ first borrow occurs due to use of `errors` in closure
    ...
    96 |     if errors.is_empty() {
       |        ^^^^^^ immutable borrow occurs here
    ...
    99 |             push_auth_requirements();
       |             ---------------------- mutable borrow later used here
    

    我该如何解决这个问题?我需要两个闭包才能修改 errors vec。

    1 回复  |  直到 1 月前
        1
  •  1
  •   sudoExclamationExclamation    1 月前

    捕获某些内容的闭包需要将其保存在(闭包的)字段中,这会导致错误,而是传递 errors 作为参数:

    let mut errors: Vec<String> = Vec::new();
    
    let msg1 = "message 1".to_string();
    let msg2 = "message 2".to_string();
    let msg3 = "message 3".to_string();
    
    let mut push_auth_requirements = |errors: &mut Vec<_>| {
        errors.push(msg1.clone());
        errors.push(msg2.clone());
    };
    
    let mut push_auth_error = |errors: &mut Vec<_>| {
        errors.push(msg3.clone());
        push_auth_requirements(errors);
    };
    
    // do some stuff
    
    if errors.is_empty() {
        // do more stuff
        if "bob" == "dsadasd" {
            push_auth_requirements(&mut errors);
        } else {
            push_auth_error(&mut errors);
        }
    }
    
    println!("Errors: {:?}", errors);