如何在 Rust 的结构中存储闭包? [英] How do I store a closure in a struct in Rust?

查看:37
本文介绍了如何在 Rust 的结构中存储闭包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Before Rust 1.0, I could write a structure using this obsolete closure syntax:

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

现在我可以执行以下操作:

Now I can do something like:

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

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

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

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

我也可以使用参考:

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

我认为这比较慢,因为

  1. 指针解引用
  2. 对于实际最终使用的 FnMut 类型没有专门化
  1. the pointer dereference
  2. there's no specialization for the type of FnMut that actually ends up being used

推荐答案

对于您在第三个代码片段中使用的类型,没有;闭包类型是匿名的,不能直接命名.相反,你会写:

For what type you'd use in your third code snippet, there isn't one; closure types are anonymous and cannot be directly named. Instead, you'd write:

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

如果您在需要指定您想要一个 Foo 的上下文中编写代码,您应该这样写:

If you're writing code in a context where you need to specify that you want a Foo, you'd write:

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

_ 告诉类型系统为您推断实际的泛型类型.

The _ tells the type system to infer the actual generic type for you.

关于使用哪个的一般经验法则,按降序排列:

The general rule of thumb as to which to use, in descending order:

  • 通用参数:struct Foo使用>.这是最有效的,但它确实意味着一个特定的 Foo 实例只能存储 一个 闭包,因为每个闭包都有不同的具体类型.
  • 特征参考:&'a mut dyn FnMut(usize) ->使用.有一个指针间接,但现在您可以存储对任何具有兼容调用签名的闭包的引用.
  • 盒装闭包:Box使用>.这涉及在堆上分配闭包,但您不必担心生命周期.与引用一样,您可以存储具有兼容签名的任何闭包.
  • Generic parameters: struct Foo<F: FnMut(usize) -> usize>. This is the most efficient, but it does mean that a specific Foo instance can only ever store one closure, since every closure has a different concrete type.
  • Trait references: &'a mut dyn FnMut(usize) -> usize. There's a pointer indirection, but now you can store a reference to any closure that has a compatible call signature.
  • Boxed closures: Box<dyn FnMut(usize) -> usize>. This involves allocating the closure on the heap, but you don't have to worry about lifetimes. As with a reference, you can store any closure with a compatible signature.

使用 || 语法的闭包是对存储在堆栈中的闭包的引用,使它们等同于 &'a mut FnMut(usize) ->使用.旧式 proc 是堆分配的,相当于 Boxusize>(你只能调用一次 proc).

Closures that used the || syntax were references to closures stored on the stack, making them equivalent to &'a mut FnMut(usize) -> usize. Old-style procs were heap-allocated and were equivalent to Box<dyn FnOnce(usize) -> usize> (you can only call a proc once).

这篇关于如何在 Rust 的结构中存储闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆