rust - 如何在另一个闭包中捕获一个闭包?

标签 rust

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_onemain,但是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/

相关文章:

rust - Rust 的 Cargo 包可以在我的机器上编译代码吗?

rust - 是否可以将 `Borrow<T>` 转换为 `AsRef<T>` 或反之亦然?

unit-testing - 通过字符串创建读取流

rust - 有没有办法在编译时获取附加程序宏的文件和模块路径?

http - 使用 std 在 Rust 中发出 HTTP 请求

rust - 通过循环和 push() 或通过 collect() 创建一个充满顺序 u64 的大型 Vec 是否更快?

rust - 复制向量中的二进制文件

polymorphism - "polymorphic"返回的 Rust 特征的简单组织

rust - cargo 单据中的下标和上标字符?

rust - Rust定制反序列化实现