我正在尝试每日程序员问题来混洗一个参数列表并输出它们.
我不确定这是否是正确的方法,但它听起来是个好主意:从args向量中删除元素,使其不会重复,并将其插入到结果向量中.
extern crate rand;
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我收到错误:
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
Run Code Online (Sandbox Code Playgroud)
让我们从一个较小的例子开始.这被称为MCVE,对于您作为程序员和我们回答您的问题非常有价值.此外,它可以在Rust Playground上运行,这很方便.
fn main() {
let mut args = vec!["a".to_string()];
let mut result = vec![];
for x 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);
}
}
Run Code Online (Sandbox Code Playgroud)
出现问题的原因是,当您打电话时swap_remove,该项目将被移出向量并提供给您 - 所有权将被转移.然后,您可以参考该项目并尝试将该引用存储在result向量中.问题是在循环迭代结束后该项被删除,因为没有任何东西拥有它.如果您被允许接受该引用,那么它将是一个悬空引用,指向无效的内存.使用该引用可能会导致崩溃,因此Rust会阻止它.
立即修复是不参考,而是将所有权从一个向量转移到另一个向量.就像是:
for x in args.iter() {
let n = args.len() - 1;
result.push(args.swap_remove(n));
}
Run Code Online (Sandbox Code Playgroud)
这个问题是你会得到的cannot borrow `args` as mutable because it is also borrowed as immutable.看到了args.iter?这会创建一个引用向量的迭代器.如果您更改了向量,那么迭代器将变为无效,并允许访问可能不存在的项目,Rust可能阻止的另一个潜在崩溃.
我没有声称这是一个很好的方法,但是有一个解决方案就是在仍有项目的情况下进行迭代:
while args.len() > 0 {
let n = args.len() - 1;
result.push(args.swap_remove(n));
}
Run Code Online (Sandbox Code Playgroud)
我通过使用shuffle以下方法解决整体问题:
extern crate rand;
use std::env;
use rand::Rng;
fn main() {
let mut args: Vec<_> = env::args().skip(1).collect();
rand::thread_rng().shuffle(&mut args);
for y in &args {
println!("{}", y);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
739 次 |
| 最近记录: |