本文介绍了如何在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< F:FnMut(usize)-> usize> 。这是最有效的,但这确实意味着特定的 Foo 实例只能存储一个闭包,因为每个闭包具有不同的具体类型

  • 特质引用:&'a mut dyn FnMut(usize)->。使用。有一个指针间接寻址,但是现在您可以存储对具有兼容调用签名的任何闭包的引用。

  • 盒装闭包: Box< dyn FnMut(usize)- > usize> 。这涉及在堆上分配闭包,但是您不必担心生存期。与参考文献一样,您可以存储具有兼容签名的任何闭包。

  • 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(使用)->使用。旧式 proc 是堆分配的,等效于 Box< dyn FnOnce(usize)->。 usize> (您只能调用一次 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的结构中存储闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 19:00