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

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型没有专门化

推荐答案

对于第三个代码段中使用的类型,这里有isn't个;闭包类型是匿名的,不能直接命名.相反,你会写:

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

如果您在need指定想要Foo的上下文中编写代码,您应该编写:

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

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

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

  • 通用参数:struct Foo<F: FnMut(usize) -> usize>.这是最有效的,但它确实意味着一个特定的Foo实例只能存储one个闭包,因 for each 闭包都有不同的具体类型.
  • trait 参考:&'a mut dyn FnMut(usize) -> usize.有一个指针间接寻址,但现在可以存储对任何具有兼容调用签名的闭包的引用.
  • 盒装封口:Box<dyn FnMut(usize) -> usize>.这涉及到在堆上分配闭包,但不必担心生命周期.与引用一样,可以使用兼容的签名存储任何闭包.

Before Rust 1.0

使用||语法的闭包是对存储在堆栈上的闭包的引用,因此它们相当于&'a mut FnMut(usize) -> usize.旧式proc是堆分配的,相当于Box<dyn FnOnce(usize) -> usize>(只能调用proc一次).

Rust相关问答推荐

在Rust中赋值变量有运行时开销吗?

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

如何指定不同的类型来常量Rust中的泛型参数?

在使用#[NO_STD]时,如何在Rust中收到紧急消息?

在Rust中,Box:ed struct 与普通 struct 在删除顺序上有区别吗?

我无法理解Rust范围的定义(Rust Programming Language,第二版克拉布尼克和尼科尔斯)

更合理的方法来设计样条线函数器?

什么是`&;[][..]`铁 rust 里的刻薄?

为什么 `Deref` 没有在 `Cell` 上实现?

要求类型参数有特定的大小?

.在 Rust 模块标识符中

RUST 中的读写器锁定模式

为什么切片时需要参考?

为什么Rust中无法推断生命周期?

为什么需要同时为值和引用实现`From`?方法不应该自动解引用或borrow 吗?(2023-06-16)

一个函数调用会产生双重borrow 错误,而另一个则不会

是否可以在 Rust 中的特定字符上实现特征?

仅在运行测试时生成调试输出

仅当满足外部条件时如何添加到 actix web 的路由

为什么-x试图解析为文字并在声明性宏中失败?