gpt4 book ai didi

list - 插入向量时为 "Borrowed Value Does Not Live Long Enough"

转载 作者:行者123 更新时间:2023-11-29 08:02:37 25 4
gpt4 key购买 nike

我正在尝试 daily programmer problem打乱参数列表并输出它们。

我不确定这是否是正确的方法,但它听起来是个好主意:从 args 向量中删除该元素以使其不会重复,然后将其插入到结果向量中。

extern crate rand; // 0.7.3

use std::io;
use std::cmp::Ordering;
use std::env;
use rand::Rng;

fn main() {
let mut args: Vec<_> = env::args().collect();
let mut result: Vec<_> = Vec::with_capacity(args.capacity());

if args.len() > 1 {
println!("There are(is) {} argument(s)", args.len() - 1)
}

for x in args.iter().skip(1) {
let mut n = rand::thread_rng().gen_range(1, args.len());
result.push(&args.swap_remove(n));
}

for y in result.iter() {
println!("{}", y);
}
}

我得到错误:

error[E0716]: temporary value dropped while borrowed
--> src/main.rs:18:22
|
18 | result.push(&args.swap_remove(n));
| ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
...
21 | for y in result.iter() {
| ------ borrow later used here
|
= note: consider using a `let` binding to create a longer lived value

老编译器说:

error[E0597]: borrowed value does not live long enough
--> src/main.rs:18:42
|
18 | result.push(&args.swap_remove(n));
| ------------------- ^ temporary value dropped here while still borrowed
| |
| temporary value created here
...
24 | }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime

最佳答案

让我们从一个较小的例子开始。这称为 Minimal, Reproducible Example ,对于您作为程序员和我们回答您的问题都非常有值(value)。此外,它可以在 Rust Playground 上运行, 这很方便。

fn main() {
let mut args = vec!["a".to_string()];
let mut result = vec![];

for _ in args.iter() {
let n = args.len() - 1; // Pretend this is a random index
result.push(&args.swap_remove(n));
}

for y in result.iter() {
println!("{}", y);
}
}

出现问题是因为当您调用 swap_remove 时,该项目被移出 向量并交给您 - 所有权被转移。然后您引用该项目并尝试将该引用存储在 result 向量中。问题是该项目在循环迭代结束后被丢弃,因为没有任何东西拥有它。如果您被允许获取该引用,它将是一个悬挂引用,指向无效内存的引用。使用该引用可能会导致崩溃,因此 Rust 会阻止它。

直接的解决方法是不采用引用,而是将所有权从一个向量转移到另一个向量。像这样的东西:

for _ in args.iter() {
let n = args.len() - 1; // Pretend this is a random index
result.push(args.swap_remove(n));
}

这样做的问题是你会得到

error[E0502]: cannot borrow `args` as mutable because it is also borrowed as immutable
--> src/main.rs:7:21
|
5 | for _ in args.iter() {
| -----------
| |
| immutable borrow occurs here
| immutable borrow later used here
6 | let n = args.len() - 1;
7 | result.push(args.swap_remove(n));
| ^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

看到args.iter了吗?这将创建一个引用向量的迭代器。如果您更改了向量,那么迭代器将变得无效,并允许访问可能不存在的项目,这是 Rust 防止的另一个潜在崩溃。

我并不是说这是一个好方法,但一种解决方案是在仍有项目时进行迭代:

while !args.is_empty() {
let n = args.len() - 1; // Pretend this is a random index
result.push(args.swap_remove(n));
}

我会使用 shuffle 解决整个问题:

use rand::seq::SliceRandom; // 0.8.3
use std::env;

fn main() {
let mut args: Vec<_> = env::args().skip(1).collect();

args.shuffle(&mut rand::thread_rng());

for y in &args {
println!("{}", y);
}
}

关于list - 插入向量时为 "Borrowed Value Does Not Live Long Enough",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31661713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com