【问题标题】:Why can't I print an array after I've taken a slice of it in Rust? [duplicate]为什么我在 Rust 中取出一个数组后不能打印一个数组? [复制]
【发布时间】:2019-03-08 14:10:49
【问题描述】:

为什么我不能将数据传递给一个函数,而该函数不会修改它并且所有权上下文没有结束?

此代码给出错误:

let mut ar = [1, 2, 3, 4, 5];
let slice = &mut ar[1..=3];
slice[1] = 9;
println!("{:?} ", slice);
for e in ar.iter(){
    println!("{}", e)
}

这是错误:

error[E0502]: cannot borrow `ar` as immutable because it is also borrowed as mutable
 --> src/main.rs:6:14
  |
3 |     let slice = &mut ar[1..=3];
  |                      -- mutable borrow occurs here
...
6 |     for e in ar.iter() {
  |              ^^ immutable borrow occurs here
...
9 | }
  | - mutable borrow ends here

我的猜测是我们无法将数组传递给println! 函数,因为我们已经借用了它,但我不明白为什么。 println! 函数不会改变它!

我发现以下行为难以理解。如果我有数组,如何打印数组?

此代码有效并打印[2, 9, 4]

let mut ar = [1, 2, 3, 4, 5];
let slice = &mut ar[1..=3];
slice[1] = 9;
println!("{:?} ", slice);

此外,这段代码可以正常工作并正确打印所有内容,通过修改切片我们修改了原始数组!

let mut ar = [1, 2, 3, 4, 5];
{
    let slice = &mut ar[1..=3];
    slice[1] = 9;
    println!("{:?} ", slice); // -> [2, 9, 4]
}
for e in ar.iter(){
    println!("{}", e) //-> 1 2 9 4 5 as expected since the slice has changed
}

【问题讨论】:

  • 又一个需要非词法生命周期的情况。
  • 我觉得不是重复的问题,我的问题是为什么我不能打印数组,求解释,不是解决问题,问题已经解决了最后一个例子。
  • 我不明白你的第二次重复,但我读到了非词法生命周期,我开始理解那里的问题......基本上编译器过于保守:-)
  • println! 是一个,而不是一个函数

标签: rust slice mutability borrowing


【解决方案1】:

如果上一个示例,您似乎已经找到了答案,但您似乎仍然有些困惑。

这里的println! 根本不是问题(请注意,这里实际上非常准确的错误消息根本没有提及)。问题是slices 变量可变地从ar 借用,当ar.iter() 尝试从ar 借用时slices 仍然存在。你不能同时有一个可变和不可变的借用,所以编译器会阻止你。

如您所见,一个解决方案是确保在您使用 ar.iter()(借用 ar)时不存在可变的 slices 借用。


至于为什么编译器会阻止你这样做,这是因为它不希望不可变借用的值从你下面意外改变。基本上,当你一成不变地借用arar.iter 时,如果底层数据突然发生变化,那就很奇怪了。但是由于slice 已经在可变地借用相同的数据,您可以在循环中放入一些代码,通过slice 更改ar,这会影响迭代器。编译器不希望你这样做。它保证你不能的方式是确保在进行不可变借用时不存在可变借用(在这种情况下为slice)。现在,它不会检查是否有代码实际上试图在循环中使用可变借用,它只是保证不可能存在。

【讨论】:

  • 这和我理解的差不多,主要是最后一个例子。但是 println 并没有改变任何东西,我认为不会发生任何副作用。如果我不遍历数组,只打印它,错误是一样的。
  • 你是对的,你的原始代码不能做任何坏事。但是因为编译器没有检查你实际上没有在循环中使用slice,只是slice 存在并且因此可以被使用,它阻止了你。当你再次借用ar时,你只需要确保slice不存在,从而让编译器放心
猜你喜欢
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多