不能借用不可变的 - String和len()

joc*_*ull 9 immutability mutability rust borrow-checker

let mut result = String::with_capacity(1000);

result.push_str("things... ");
result.push_str("stuff... ");

result.truncate((result.len() - 4));
Run Code Online (Sandbox Code Playgroud)

但是,这是一个编译错误.与借用检查器有关,可能还有可变性.

error[E0502]: cannot borrow `result` as immutable because it is also borrowed as mutable
 --> <anon>:7:22
  |
7 |     result.truncate((result.len() - 4));
  |     ------           ^^^^^^           - mutable borrow ends here
  |     |                |
  |     |                immutable borrow occurs here
  |     mutable borrow occurs here
Run Code Online (Sandbox Code Playgroud)

然而,如果我稍微改变它,我可以这样做:

let newlen = result.len() - 4;
result.truncate(newlen);
Run Code Online (Sandbox Code Playgroud)

为什么?有没有办法改变它,所以它可以写在一行?(PS这是在Rust 1.0上)

Vla*_*eev 10

这是Rust借阅检查程序的一个不幸的缺点.这基本上是因为

result.truncate(result.len() - 2)
Run Code Online (Sandbox Code Playgroud)

相当于

String::truncate(&mut result, result.len() - 2)
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到,因为参数是按从左到右的顺序计算的,result所以在使用它之前确实是可变的result.len().

我在Rust问题跟踪器中发现了这个问题:#6268.这个问题被关闭,有利于非词汇借用RFC问题.看起来它只是其中一个很好的东西,但需要更多的时间来完成它在1.0之前可用.这篇文章也可能有一些兴趣(即使它差不多两年了).