当函数返回具有相同生存期的引用时,Rust Borrow checker只会抱怨多次借用是可变的

当函数返回具有相同生存期的引用时,Rust Borrow checker只会抱怨多次借用是可变的,rust,lifetime,borrow-checker,Rust,Lifetime,Borrow Checker,我遇到了一些锈代码的问题,在某些情况下(第一个令人困惑的部分),我被允许多次借用可变的东西,但在其他情况下,我却不能借用 我编写了以下示例来说明: () struct NoLifetime{} 带生存期字符串的结构{ “abc”。to_string() } fn借用寿命和'a i32{ 瓦卢 } 如果你看到了,我可以多次借用some_val,以及life_val作为可变的。但是,在分配了借用\u life的返回值后,我无法再借用 我的问题如下: 根据中关于借用的“规则”,我应该在范围中对相同的

我遇到了一些锈代码的问题,在某些情况下(第一个令人困惑的部分),我被允许多次借用可变的东西,但在其他情况下,我却不能借用

我编写了以下示例来说明: ()

struct NoLifetime{}
带生存期字符串的结构{
“abc”。to_string()
}
fn借用寿命和'a i32{
瓦卢
}
如果你看到了,我可以多次借用
some_val
,以及
life_val
作为可变的。但是,在分配了
借用\u life
的返回值后,我无法再借用

我的问题如下:

  • 根据中关于借用的“规则”,我应该在范围中对相同的值有“恰好一个可变引用”。然而,在上面的代码中,每次调用
    brooke\uu
    函数时,我都将借用作为可变的
  • 当我有一个函数返回与参数具有相同生存期的内容,并且我分配了该参数时,为什么不允许使用相同类型的借用

  • 任何帮助都将不胜感激。我想这里发生的事情是,我误解了“作为可变项借用”的真正含义,以及何时确定某些东西是作为可变项借用的。

    这是关于借用的范围,以及是否保持借用的有效性。在上述大多数调用中,
    some_val
    在函数调用期间借用,但在函数返回后返回

    在例外情况下:

    let num_again = borrow_lifetime(&mut life_val); //Borrow, assign lifetime result
    

    在调用
    借用生命周期
    期间,您借用的是
    生命周期
    ,但由于返回值与参数(
    'a
    )具有相同的生命周期,因此借用的范围将扩展为再次包括
    num_的生命周期
    ,即直到函数结束。再次借用
    life\u val
    是不安全的,因为再次借用
    num\u
    仍然是对它的引用。

    这是关于借用的范围,以及您是否保持借用活动。在上述大多数调用中,
    some_val
    在函数调用期间借用,但在函数返回后返回

    在例外情况下:

    let num_again = borrow_lifetime(&mut life_val); //Borrow, assign lifetime result
    
    在调用
    借用生命周期
    期间,您借用的是
    生命周期
    ,但由于返回值与参数(
    'a
    )具有相同的生命周期,因此借用的范围将扩展为再次包括
    num_的生命周期
    ,即直到函数结束。再次借用
    life\u val
    是不安全的,因为再次借用
    num\u
    仍然是对它的引用。

    ,但我认为值得进一步解释

    转让Rust所有权的方法有两种:

    • 移动是一种永久性的转移
    • 借款是一种临时转让,预计所有权将返还
    与许多其他语言一样,Rust使用一堆词汇作用域来模拟时间的流逝。因此,就目前而言,借用从创建位置开始,并一直延伸到其作用域的末尾


    因此,借用何时结束的问题类似于询问借用是在什么范围内创建的

    让我们用编号的行回顾一下您的示例:

    fn main() {
        let mut some_val = NoLifetime {};                // 1
        borrow_mut_function(&mut some_val);              // 2
        borrow_mut_function(&mut some_val);              // 3
                                                         // 
        let num = 5;                                     // 4
        let mut life_val = WithLifetime { field: &num }; // 5
        borrow_lifetime(&mut life_val);                  // 6
        borrow_lifetime(&mut life_val);                  // 7
                                                         //
        let num_again = borrow_lifetime(&mut life_val);  // 8
        borrow_lifetime(&mut life_val);                  // 9
    }
    
    调用函数时,将借用参数:

    • 至少在函数调用期间
    • 直到结果被删除的那一刻,如果结果与参数共享一个生命周期
    那么,让我们看看这个:

    • 在第(2)行和第(3)行中,您调用了
      borrow_mut_函数
      ,该函数返回一个
      字符串
      :结果不与参数共享任何生存期,因此参数仅在函数调用的生存期内被借用

    • 在第(6)行和第(7)行中,您调用
      借用生命周期
      ,它返回一个
      和一个i32
      :结果与参数共享一个生命周期,因此参数被借用,直到结果范围结束。。。因为结果未使用,因此立即进行

    • 在第(8)行中,您调用
      borrow_life
      ,它返回一个
      和一个i32
      ,并再次将结果分配给
      num_
      :结果与参数共享一个生存期,因此参数被借用,直到
      num_
      的范围结束

    • 在第(9)行中,您调用了
      borrow\u lifetime
      ,但是它的参数仍然是blow by
      num\u
      ,因此该调用是非法的

    就是这样,这就是今天生锈的原因


    在未来,有一个呼吁。也就是说,编译器会意识到:

    • num\u再次使用
    • num\u再次
      没有特定的析构函数(无
      Drop
      实现)
    因此可以决定它的借词结束比词法范围的结束早。

    ,但我认为值得进一步解释

    转让Rust所有权的方法有两种:

    • 移动是一种永久性的转移
    • 借款是一种临时转让,预计所有权将返还
    与许多其他语言一样,Rust使用一堆词汇作用域来模拟时间的流逝。因此,就目前而言,借用从创建位置开始,并一直延伸到其作用域的末尾


    因此,借用何时结束的问题类似于询问借用是在什么范围内创建的

    让我们用编号的行回顾一下您的示例:

    fn main() {
        let mut some_val = NoLifetime {};                // 1
        borrow_mut_function(&mut some_val);              // 2
        borrow_mut_function(&mut some_val);              // 3
                                                         // 
        let num = 5;                                     // 4
        let mut life_val = WithLifetime { field: &num }; // 5
        borrow_lifetime(&mut life_val);                  // 6
        borrow_lifetime(&mut life_val);                  // 7
                                                         //
        let num_again = borrow_lifetime(&mut life_val);  // 8
        borrow_lifetime(&mut life_val);                  // 9
    }
    
    调用函数时,将借用参数:

    • 至少在函数调用期间
    • 直到结果被删除的那一刻,如果结果与参数共享一个生命周期
    那么,让我们看看这个:

    • 在线(2)a