functionA
返回closureA
,而closureA
返回closureB
,closureB
,它们使用来自functionA
周围环境的变量。
fn main () {
type Closure1 = Box<Fn() -> ()>;
type Closure2 = Box<Fn() -> Closure1>;
fn closure_container() -> Closure2 {
let mut a: Vec<usize> = Vec::new();
let closure2: Closure2 = Box::new(move || {
let closure1 = || {
println!("{}", a)
};
Box::new(closure1)
});
closure2
}
}
error[E0507]: cannot move out of captured outer variable in an `Fn` closure
--> src/main.rs:9:27
|
6 | let mut a: Vec<usize> = Vec::new();
| ----- captured outer variable
...
9 | let closure1 = move || {
| ^^^^^^^ cannot move out of captured outer variable in an `Fn` closure
它将编译let mut a = 100;
,但是let mut a: Vec<usize> = Vec::new();
将报告错误!我不知道如何解决。
答案 0 :(得分:1)
您(正确地)将function add_content_after_addtocart() {
global $woocommerce;
// get the current post/product ID
$current_product_id = get_the_ID();
// get the product based on the ID
$product = wc_get_product( $current_product_id );
// get the "Checkout Page" URL
$checkout_url = WC()->cart->get_checkout_url();
// run only on simple products
if( $product->is_type( 'variable' ) ){
?>
<script>
jQuery(function($) {
<?php /* if our custom button is clicked, append the string "&quantity=", and also the quantitiy number to the URL */ ?>
// if our custom button is clicked
$(".custom-checkout-btn").on("click", function() {
// get the value of the "href" attribute
$(this).attr("href", function() {
// return the "href" value + the string "&quantity=" + the current selected quantity number
return this.href + '&quantity=' + $('input.qty').val();
});
});
});
</script>
<?php
echo '<div class="col-sm-6"><div class="buy_now"><a href="'.$checkout_url.'?add-to-cart='.$current_product_id.'" class="single_add_to_cart_button buy_now_button button alt disabled custom-checkout-btn ajax_add_to_cart" >Buy Now</a></div></div><div class="clearfix"></div>';
?>
<?php
}
else if( $product->is_type( 'simple' ) ){
echo '</div><div class="col-sm-6"><div class="p-t-35"></div><div class="buy_now"><a href="'.$checkout_url.'?add-to-cart='.$current_product_id.'" class="single_add_to_cart_button button alt buy_now_button button alt">Buy Now</a></div></div><div class="clearfix"></div>';
}
}
add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart' );
用于第一个闭包(第7行),但还需要将其添加到第二个闭包(第8行):
move
如果 let closure2: Closure2 = Box::new(move || {
let closure1 = move || { // <-- Add "move" on this line
println!("{}", a)
};
Box::new(closure1)
});
具有a
类型,则可以工作,但是当Copy
不是cannot move out of captured outer variable in an 'Fn' closure
时(例如,如果{{ 1}}是a
)。问题是由于您将Copy
定义为a
的事实,这意味着您正在告诉编译器您可能想多次调用它。但是,第一次调用Vec
会将closure2
移到返回的Fn
中,因此closure2
将不可用于下一次对a
的调用。
长话短说:您需要将closure1
定义为a
,以告诉编译器您不能多次调用它,或者您需要移动closure2
的副本放入closure2
中,以便FnOnce
保留其副本。
a
closure1
但是请注意,尽管您可以通过这种方式创建 closure2
,但是在当前稳定的Rust中无法调用。如果您愿意每晚使用,则将FnOnce
替换为FnBox
应该可以,但是我遇到了另一个错误(playground)。目前,您将需要使用解决方案2并克隆type Closure1 = Box<Fn() -> ()>;
type Closure2 = Box<FnOnce() -> Closure1>;
fn closure_container() -> Closure2 {
let a: Vec<usize> = Vec::new();
let closure2: Closure2 = Box::new(move || {
let closure1 = move || {
println!("{:?}", a)
};
Box::new(closure1)
});
closure2
}
。如果要避免克隆整个载体的开销,可以wrap it in an Rc
and clone that(playground)。
Closure2