我知道借阅检查器不允许多个可变借阅。例如,下面的代码无效:
fn main() {
let mut x = 42;
let a = &mut x;
let b = &mut x;
println!("{} {}", a, b);
}
但是,如果第一次借款因超出范围而被放弃,第二次借款是有效的:
fn main() {
let mut x = 1;
{
let a = &mut x;
println!("{}", a);
}
let b = &mut x;
println!("{}", b);
}
由于非词汇生存期(NLL),第一次借用甚至不必超出范围-借用检查器只要求不再使用它。因此,以下代码在2018年有效:
fn main() {
let mut x = 1;
let a = &mut x;
println!("{}", a);
let b = &mut x;
println!("{}", b);
}
但我不明白为什么下面的代码无效:
use std::str::Chars;
fn main() {
let s = "ab".to_owned();
let mut char_iter = s.chars();
let mut i = next(&mut char_iter);
dbg!(i.next());
let mut j = next(&mut char_iter);
dbg!(j.next());
}
fn next<'a>(char_iter: &'a mut Chars<'a>) -> impl Iterator<Item = char> + 'a {
char_iter.take_while(|&ch| ch != ' ')
}
编译错误信息:
error[E0499]: cannot borrow `char_iter` as mutable more than once at a time
--> src/main.rs:10:22
|
7 | let mut i = next(&mut char_iter);
| -------------- first mutable borrow occurs here
...
10 | let mut j = next(&mut char_iter);
| ^^^^^^^^^^^^^^ second mutable borrow occurs here
11 | dbg!(j.next());
12 | }
| - first borrow might be used here, when `i` is dropped and runs the destructor for type `impl std::iter::Iterator`
从错误消息中,我认为NLL可能还不支持这种情况。所以,我提前删除了i
:
use std::str::Chars;
fn main() {
let s = "ab".to_owned();
let mut char_iter = s.chars();
{
let mut i = next(&mut char_iter);
dbg!(i.next());
}
let mut j = next(&mut char_iter);
dbg!(j.next());
}
fn next<'a>(char_iter: &'a mut Chars<'a>) -> impl Iterator<Item = char> + 'a {
char_iter.take_while(|&ch| ch != ' ')
}
(铁锈操场)
但我得到了一个更令人困惑的错误信息:
error[E0499]: cannot borrow `char_iter` as mutable more than once at a time
--> src/main.rs:12:22
|
8 | let mut i = next(&mut char_iter);
| -------------- first mutable borrow occurs here
...
12 | let mut j = next(&mut char_iter);
| ^^^^^^^^^^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
为什么它会说第一次借用后来在这里使用
,即使i
以前已经被删除并超出了范围?
如果我将next
函数的签名更改为:
fn next(char_iter: impl Iterator<Item = char>) -> impl Iterator<Item = char> {
char_iter.take_while(|&ch| ch != ' ')
}
但我还是想理解为什么原来的next
函数不起作用。
问题在于,您明确地告诉借阅检查器,i
与char_iter
在下一个块中的寿命一样长,方法是声明两者具有相同的寿命'a
。
fn next<'a>(char_iter: &'a mut Chars<'a>) -> impl Iterator<Item = char> + 'a {
char_iter.take_while(|&ch| ch != ' ')
}
这意味着编译器认为
impl Iterator
实际上是一个具体的类型:Chars
,它用Take虽然
包装,所以您可以像这样重写您的方法(顺便说一句,一个有趣的任务是确定
fn next<'a>(
char_iter: &'a mut Chars<'a>,
) -> TakeWhile<&'a mut Chars<'a>, impl FnMut(&char) -> bool> {
char_iter.take_while(|&ch| ch != ' ')
}
现在您可能会看到,输出类型的寿命与输入相同,反之亦然。事实上,这个生命周期是从
fn next<'a, 'b: 'a>(
char_iter: &'a mut Chars<'b>,
) -> TakeWhile<&'a mut Chars<'b>, impl FnMut(&char) -> bool> {
char_iter.take_while(|&ch| ch != ' ')
}
如果我有一个封装两个成员的结构,并基于另一个成员更新其中一个,那么只要我这样做就可以了: 也就是说,当我直接提到self时。b 。但当我将do\u stuff()更改为以下内容时: 编译器抱怨:<代码>无法将`*self`借用为不可变,因为` self `。a `也被借用为可变的。 如果我需要执行比返回成员更复杂的操作来获取a.do\u something()的参数,该怎么办?我必须创建一个按值返
可变数据可以使用 &mut T 进行可变借用。这叫做可变引用(mutable reference),并赋予了借用者读/写访问能力。相反,&T 通过不可变引用(immutable reference)来借用数据,借用者可以读数据而不能更改数据: #[allow(dead_code)] #[derive(Clone, Copy)] struct Book { // `&'static str`
问题内容: 我想检查一个变量是否具有多个值之一。我对为什么在这种情况下不起作用感到困惑。我正在按照给出该示例的教程进行操作,但是当我尝试执行此操作时,它只会根据第一个值检查变量。我的支票怎么了? 问题答案: (“Jesse” or “jesse”) 上面的表达式测试是否评估为。如果是这样,则表达式将返回它;否则,它将返回。该表达式等同于编写: 因为是一个非空字符串,所以它将 始终 求值为并因此返回
来自C++,我很惊讶这段代码在Rust中是有效的: 在C++中,您不能使用临时的地址,并且临时的时间不会超过它出现在其中的表达式。 临时工在铁锈中生活多长时间?而且由于只是一个借方,那么字符串的所有者是谁呢?
我正试着用铁锈的雪球词干分析器板条箱来词干。这应该很简单,但借用检查器一直拒绝我的代码: 借用检查器说我在