【发布时间】:2015-12-08 19:11:09
【问题描述】:
再次尝试 VisualRust,看看他们能走多远,我写了几行代码。和往常一样,代码让我在stackoverflow上写了一个问题......
先看,再看我的问题:
fn make_counter( state : &mut u32 ) -> Box<Fn()->u32>
{
Box::new(move || {let ret = *state; *state = *state + 1; ret })
}
fn test_make_counter() {
let mut cnt : u32 = 0;
{
let counter = make_counter( & mut cnt );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
}
fn alt_make_counter ( init : u32 ) -> Box<Fn()->u32> {
let mut state = init;
Box::new(move || {let ret = state; state = state + 1; ret })
}
fn test_alt_make_counter() {
let counter = alt_make_counter( 0u32 );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
fn main() {
test_make_counter();
test_alt_make_counter();
}
make_counter() 和alt_make_counter() 之间的区别在于,在一种情况下,状态是指向传递给函数的可变 u32 的指针,而在另一种情况下,它是在函数内部定义的可变 u32。正如 test_make_counter() 函数清楚地表明的那样,闭包的寿命不可能比变量 cnt 长。即使我删除了test_make_counter() 中的块,它们仍然具有相同的生命周期。使用该块,counter 将在cnt 之前死亡。然而,Rust 抱怨道:
src\main.rs(4,2): 错误:捕获的变量
state不会超过封闭的闭包 src\main.rs(3,1):警告:注意:捕获的变量在 3:0 的块上定义的匿名生命周期 #1 内有效
如果你现在看alt_make_counter() 函数,state 的生命周期基本上应该会导致相同的错误信息,对吧?如果代码捕获了闭包的状态,那么是否传入指针或变量是否绑定在函数内部都无关紧要,对吧?但很明显,这两种情况是完全不同的。
谁能解释它们为什么不同(错误、功能、深刻见解……?),以及是否有一个可以采用的简单规则来防止不时在此类问题上浪费时间?
【问题讨论】: