type Time = f32;
type Behaviour<'a,T> = |Time|: 'a -> T;
fn map_one<'a,T,R>(f: |T| -> R
,b: Behaviour<'a,T>)
-> Behaviour<'a,R>{
|time| -> R {
f(b(time))
}
}
错误:
<anon>:8:9: 8:10 error: captured variable `b` does not outlive the enclosing closure
<anon>:8 f(b(time))
^
<anon>:6:38: 10:2 note: captured variable is valid for the block at 6:37
<anon>:6 -> Behaviour<'a,R>{
<anon>:7 |time| -> R {
<anon>:8 f(b(time))
<anon>:9 }
<anon>:10 }
我认为错误意味着当我尝试将 b
移动到另一个闭包时 'a 的生命周期到期。
我该如何表达这样的东西?
最佳答案
您的代码使用“盒装”闭包。这些闭包通过引用捕获值,因此捕获的值必须比闭包存在的时间更长。您正在 try catch b
,这是一个参数,因此它的生命周期就是函数调用的持续时间。你不能用“盒装闭合”做你想做的事。
未装箱的闭包被添加到语言中以解决此类问题。以下是 map_one
的定义方式:
#![feature(overloaded_calls, unboxed_closures, unboxed_closure_sugar)]
type Time = f32;
fn map_one<'a, T, R, F: Fn<(T,), R>, B: Fn<(Time,), T>>(
f: F, b: B) -> Box<Fn<(Time,), R>+'a> {
box |&: time| -> R {
f(b(time))
}
}
Fn
是具有 call
方法的特征,该方法通过不可变引用获取 self
(FnMut
获取 self
通过可变引用和 FnOnce
通过值获取 self
)。捕获的值被移动到闭包中,而不是被引用。
输入闭包参数是用实现Fn
特性的类型参数定义的,这是按值传递闭包的唯一方法。然而,返回值必须被装箱,因为具体的结果类型(实现了 Fn
)是由编译器创建的,我们无法命名它。
我尝试编写一个使用map_one
的main
,但是I'm getting an internal compiler error ... 在这一点上,我不知道我是否犯了错误或者代码是否应该有效。 (这些 Rust 问题可能与此错误有关:#16672、#16791、#17060。)
fn main() {
let t = 30f32;
let fa = |&: a: String| -> uint { a.len() };
let fb = |&: b: f32| -> String { b.to_string() };
let m = map_one(fa, fb);
let r = m.call((t,));
println!("{}", r);
}
注意:我无法使用您的Behaviour
泛型类型别名来绑定(bind)B
。
#![feature(overloaded_calls, unboxed_closures, unboxed_closure_sugar)]
type Time = f32;
type Behaviour<T> = Fn<(Time,), T>;
fn map_one<'a, T, R, F: Fn<(T,), R>, B: Behaviour<T>>(
f: F, b: B) -> Box<Behaviour<R>+'a> {
box |&: time| -> R {
f(b(time))
}
}
编译器提示:
<anon>:6:41: 6:53 error: `Behaviour` is not a trait
<anon>:6 fn map_one<'a, T, R, F: Fn<(T,), R>, B: Behaviour<T>>(
^~~~~~~~~~~~
<anon>:6:41: 6:53 note: `type` aliases cannot be used for traits
<anon>:6 fn map_one<'a, T, R, F: Fn<(T,), R>, B: Behaviour<T>>(
^~~~~~~~~~~~
关于rust - 如何在另一个闭包中捕获一个闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26070189/