我偶然发现了一个在文档中有static || { }个有效的例子.然而,在我自己的代码中使用这种表达式的try 失败了.我想知道为什么.

来自https://doc.rust-lang.org/stable/std/pin/macro.pin.html个人的例子

#![feature(generators, generator_trait)]
use std::{
    ops::{Generator, GeneratorState},
    pin::pin,
};

fn generator_fn() -> impl Generator<Yield = usize, Return = ()> /* not Unpin */ {
 // Allow generator to be self-referential (not `Unpin`)
 // vvvvvv        so that locals can cross yield points.
    static || {
        let foo = String::from("foo");
        let foo_ref = &foo; // ------+
        yield 0;                  // | <- crosses yield point!
        println!("{foo_ref}"); // <--+
        yield foo.len();
    }
}

fn main() {
    let mut generator = pin!(generator_fn());
    match generator.as_mut().resume(()) {
        GeneratorState::Yielded(0) => {},
        _ => unreachable!(),
    }
    match generator.as_mut().resume(()) {
        GeneratorState::Yielded(3) => {},
        _ => unreachable!(),
    }
    match generator.resume(()) {
        GeneratorState::Yielded(_) => unreachable!(),
        GeneratorState::Complete(()) => {},
    }
}

我的try 失败了:

fn func() -> impl Fn() {
    static || {
        println!("qwerty");
    }
}

出现以下错误:

error[E0697]: closures cannot be static
 --> ./ex_099.rs:2:5
  |
2 |     static || {
  |     ^^^^^^^^^

铁 rust 版本:

$ rustc --version
rustc 1.70.0-nightly (88fb1b922 2023-04-10)

推荐答案

在 compose 本文时,Rust稳定工具链不以任何方式支持静态闭包.您看到的是不稳定特性generators的使用,它求助于类似闭包的语法来表示generator functions.引用几个相关部分:

生成器是一个"可恢复函数",它在语法上类似于闭包,但在编译器本身中编译成非常不同的语义.[.]生成器使用关键字yield来"返回",然后调用方可以继续生成器以继续执行,紧跟在Year关键字之后.

[.]

生成器是closure-like个文字,可以包含yield条语句.yield语句接受生成器输出的值的可选表达式.所有生成器文字都在std::ops模块中实现Generator特征

作为一项不稳定的功能,有关其功能的任何细节都可能发生变化.从nightly-2023-04-02开始,语法static || { /* ... */ }只有在添加了必要的特性属性、使函数返回impl Generator而不是impl Fn,并且在生成器中至少包含一个yield的情况下才能使用.

#![feature(generators, generator_trait)]
use std::ops::Generator;

fn func() -> impl Generator<Yield = (), Return = ()> {
    static || {
        yield;
        println!("qwerty");
    }
}

Playground

另见:

Rust相关问答推荐

无需通过ASIO输入音频,并使用cpal进行反馈示例

当第二个`let`依赖于第一个`let()`时,如何在一行中有多个`let()`?

S在Cargo.toml中添加工作空间开发依赖关系的正确方法是什么?

`*mut[T]`与`*mut T`的区别

在0..1之间将U64转换为F64

&'a T 是否意味着 T: 'a?

如何在 `connect_activate()` 之外创建一个 `glib::MainContext::channel()` 并将其传入?

如何在 Rust 中将函数项变成函数指针

Rust 中指向自身的引用如何工作?

pyO3 和 Panics

从光标位置旋转精灵

从 Rust 中的 if/else 中的引用创建 MappedRwLockWriteGuard

从 HashMap>, _> 中删除的生命周期问题

Rust/Serde/HTTP:序列化`Option`

通用函数中的生命周期扣除和borrow (通用测试需要)

相交着色器从 SSBO 中读取零

Rust:如果我知道只有一个实例,那么将可变borrow 转换为指针并返回(以安抚borrow 判断器)是否安全?

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?

类型参数不受 impl 特征、自身类型或谓词的约束

函数参数的 Rust 功能标志