closures - 如何在 Rust 的结构中存储闭包?

标签 closures rust

在 Rust 1.0 之前,我可以使用这种过时的闭包语法编写一个结构:

struct Foo {
    pub foo: |usize| -> usize,
}

现在我可以做类似的事情:

struct Foo<F: FnMut(usize) -> usize> {
    pub foo: F,
}

但是我创建的 Foo 对象的类型是什么?

let foo: Foo<???> = Foo { foo: |x| x + 1 };

我也可以使用引用:

struct Foo<'a> {
    pub foo: &'a mut FnMut(usize) -> usize,
}

我认为这比较慢,因为

  1. 指针解引用
  2. 对于实际最终使用的 FnMut 类型没有专门化

最佳答案

补充 the existing answer还有一些用于演示目的的代码:

未装箱闭包

使用通用类型:

struct Foo<F>
where
    F: Fn(usize) -> usize,
{
    pub foo: F,
}

impl<F> Foo<F>
where
    F: Fn(usize) -> usize,
{
    fn new(foo: F) -> Self {
        Self { foo }
    }
}

fn main() {
    let foo = Foo { foo: |a| a + 1 };
    (foo.foo)(42);
    
    (Foo::new(|a| a + 1).foo)(42);
}

盒装特征对象

struct Foo {
    pub foo: Box<dyn Fn(usize) -> usize>,
}

impl Foo {
    fn new(foo: impl Fn(usize) -> usize + 'static) -> Self {
        Self { foo: Box::new(foo) }
    }
}

fn main() {
    let foo = Foo {
        foo: Box::new(|a| a + 1),
    };
    (foo.foo)(42);
    
    (Foo::new(|a| a + 1).foo)(42);
}

性状对象引用

struct Foo<'a> {
    pub foo: &'a dyn Fn(usize) -> usize,
}

impl<'a> Foo<'a> {
    fn new(foo: &'a dyn Fn(usize) -> usize) -> Self {
        Self { foo }
    }
}

fn main() {
    let foo = Foo { foo: &|a| a + 1 };
    (foo.foo)(42);
    
    (Foo::new(&|a| a + 1).foo)(42);
}

函数指针

struct Foo {
    pub foo: fn(usize) -> usize,
}

impl Foo {
    fn new(foo: fn(usize) -> usize) -> Self {
        Self { foo }
    }
}

fn main() {
    let foo = Foo { foo: |a| a + 1 };
    (foo.foo)(42);
    
    (Foo::new(|a| a + 1).foo)(42);
}

what's the type of a Foo object I create?

这是一个无法命名的自动生成的类型。

I could also use a reference [...] slower because [...] the pointer deref [...] no specialization

也许吧,但这对调用者来说会容易得多。

另见:

关于closures - 如何在 Rust 的结构中存储闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27831944/

相关文章:

javascript - 我怎样才能通过闭包问题来增加全局变量

rust - 如何获取 glium 的宽度和高度?

c# - 从 C# 调用 F# 函数并获取空引用异常

javascript - 此回调引用了取消引用的闭包吗?

sorting - 如何对带有 map 状闭包的Rust Vector进行排序?

rust - 是否可以仅在运行测试时为结构实现特征?

iterator - 如何跳过 Rust 迭代器中的第 N 个元素?

rust - 如何固定 crate 的间接依赖项?

generics - Rust:缩短泛型类型界限

swift - 在嵌套函数中使用闭包如何逃逸?