考虑以下计划:
fn primes_up_to(n: usize) -> Vec<usize> {
let mut ans = Vec::with_capacity(n);
if n < 2 {
return ans;
}
ans.push(2);
// https://doc.rust-lang.org/1.22.0/book/first-edition/closures.html#closures-and-their-environment
// The closure needs ownership of vec to access elements
let is_prime = |n: usize| -> bool {
for x in ans {
if x * x > n {
break;
}
if n % x == 0 {
return false;
}
}
true
};
let mut i = 3;
while i <= n {
if is_prime(i) {
ans.push(i);
}
i += 2;
}
ans
}
fn main() {
println!("{:?}", primes_up_to(23));
}
编译上面的代码会产生以下编译错误:
error[E0382]: use of moved value: `is_prime`
--> src/main.rs:28:12
|
28 | if is_prime(i) {
| ^^^^^^^^ value moved here in previous iteration of loop
|
note: closure cannot be invoked more than once because it moves the variable `ans` out of its environment
--> src/main.rs:13:18
|
13 | for x in ans {
| ^^^
error[E0382]: use of moved value: `ans`
--> src/main.rs:29:13
|
12 | let is_prime = |n: usize| -> bool {
| ------------------ value moved (into closure) here
...
29 | ans.push(i);
| ^^^ value used here after move
|
= note: move occurs because `ans` has type `std::vec::Vec<usize>`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `ans`
--> src/main.rs:35:5
|
12 | let is_prime = |n: usize| -> bool {
| ------------------ value moved (into closure) here
...
35 | ans
| ^^^ value used here after move
|
= note: move occurs because `ans` has type `std::vec::Vec<usize>`, which does not implement the `Copy` trait
我知道一个可能的解决方案是将ans
(&ans
)的不可变引用传递给is_prime
。 ans
的所有权转换为is_prime
的惯用方式是什么?每次拨打is_prime
时is_prime
退出时都会退出?
答案 0 :(得分:3)
如何从闭包中获取移动值的所有权
你没有。
一旦所有权转移,它就消失了。 “让它回来”的唯一方法是让现在拥有的东西将其转回。出于这个原因,某些类型具有DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(stage);
if(selectedDirectory == null){
//No Directory selected
}else{
System.out.println(selectedDirectory.getAbsolutePath());
}
方法。其他类型有相同的方法。
根据定义,闭包的唯一接口是调用它的能力。方法没有其他可能性。
你可以在完成后返回捕获的值,但这对你的情况没有帮助,因为你需要多次调用闭包 - 你无法返回它,因为将来可能需要它。
答案 1 :(得分:1)
您的代码存在一些问题:
$datArr = array(
array(
"name" => "Ram",
"id" => 1,
"date" => "12/04/2017 05:31:57"
),
array(
"name" => "Rahim",
"id" => 5,
"date" => "12/03/2017 12:31:57"
),
array(
"name" => "Raj",
"id" => 4,
"date" => "12/04/2017 05:31:57"
)
);
闭包不能多次调用,因为它会移动变量
for x in ans {
退出其环境:
每个ans
所以你应该在这一行中完全借用ans.push(i);
:
ans
然后把它还给下一行:
if is_prime(i) {
解决方案是将其作为参数传递:
ans.push(i);
或试试这个,它在夜间频道的发布模式中具有与上述相同的fn primes_up_to(n: usize) -> Vec<usize> {
let mut ans = Vec::with_capacity(n);
if n < 2 {
return ans;
}
ans.push(2);
let is_prime = |n: usize, v: &[usize]| -> bool {
for x in v {
if x * x > n {
break;
}
if n % x == 0 {
return false;
}
}
true
};
let mut i: usize = 3;
while i <= n {
if is_prime(i, &ans) {
ans.push(i);
}
i += 2;
}
ans
}
fn main() {
println!("{:?}", primes_up_to(23));
}
足迹:
ASM
输出:
fn primes_up_to(n: usize) -> Vec<usize> {
let mut ans = Vec::with_capacity(n);
if n < 2 {
return ans;
}
ans.push(2);
let is_prime = |n: usize, v: &Vec<usize>| -> bool {
for x in v {
if x * x > n {
break;
}
if n % x == 0 {
return false;
}
}
true
};
let mut i: usize = 3;
while i <= n {
if is_prime(i, &ans) {
ans.push(i);
}
i += 2;
}
ans
}
fn main() {
println!("{:?}", primes_up_to(23));
}