Crius图书馆提供

pub struct Command<P, T, CMD>
where
    T: Send,
    CMD: Fn(P) -> Result<T, Box<CommandError>> + Sync + Send,
{
    pub config: Option<Config>,
    pub cmd: CMD,
    phantom_data: PhantomData<P>,
}

是否可以将Command的实例存储为另一个 struct 中的字段?

我开始try 从

/// This function constructs a simple instance of `Command<P, T, CMD>` with the
/// types set to:
///
///     P ~ u8
///     T ~ u8
///     CMD: Fn(u8) -> Result<u8, Box<CommandError>> + Send + Sync
///
/// This function compiles fine. However, there is no *concrete* type
/// for `CMD`. In compiler output it will be referred to as an
/// "anonymous" type looking like this:
///
///    Command<u8, u8, [closure@src/lib.rs:19:21: 19:38]>
fn simple_command_instance() {
    let _ = Command::define(|n: u8| Ok(n * 2));
}

当为

fn return_command_instance() -> Command<u8, u8, ???> {
                                                ^
                                                |
                          What goes here? -------

    Command::define(|n: u8| Ok(n * 2))
}

编译器推断出的类型是匿名的,无法放入

在具有新impl Trait功能的Rust版本中(例如

/// Use new `impl Trait` syntax as a type parameter in the return
/// type:
fn impl_trait_type_param() -> Command<u8, u8, impl Fn(u8) -> Result<u8, Box<CommandError>>> {
    Command::define(|n: u8| Ok(n * 2))
}

这在稳定Rust 的情况下不起作用,impl Trait只能

试图传播泛型类型的结果是

fn return_cmd_struct<F>() -> Command<u8, u8, F>
where
    F: Fn(u8) -> Result<u8, Box<CommandError>> + Send + Sync,
{
    Command::define(|n: u8| Ok(n * 2))
}

但这并没有编译:

error[E0308]: mismatched types
  --> src/lib.rs:33:21
   |
33 |     Command::define(|n: u8| Ok(n * 2))
   |                     ^^^^^^^^^^^^^^^^^ expected type parameter, found closure
   |
   = note: expected type `F`
              found type `[closure@src/lib.rs:33:21: 33:38]`

再说一遍,我不知道有什么方法可以在


即使将类型作为泛型参数传播有效,它也会

如果有人对此有任何 idea ,请分享

推荐答案

我目前知道,除了使用implBox之外,没有其他方法可以将闭包用作返回类型的一部分,这两种方法您都提到过,在这种情况下不能使用.

另一种方法是使用函数指针而不是闭包,如下所示:

fn return_command_instance() -> Command<u8, u8, fn(u8) -> Result<u8, Box<CommandError>>> {
    Command::define(|n: u8| Ok(n * 2))
}

请注意,小写字母fn表示函数指针,而不是特征Fn.这在关于Advanced Functions & Closures的章节中有更详细的解释.

只有在函数中没有捕获任何变量的情况下,这才有效,如果捕获,它将被编译成闭包.

Rust相关问答推荐

使用InlineTables序列化toml ArrayOfTables

如何在Rust中在屏幕中间打印内容?

go 掉包装 struct 中的泛型

在特征中使用Async时,如何解决不透明类型`impl Future<;out=self>;`不满足其关联的类型边界和警告?

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

无法定义名为&new&的关联函数,该函数的第一个参数不是self

创建Rust中元对象协议的动态对象 Select /重新分配机制

是否可以在不切换到下一个位置的情况下获得迭代器值:

在Rust中判断编译时是否无法访问

允许 rust 迹 struct 条目具有多种类型

由于生存期原因,返回引用的闭包未编译

为什么特征默认没有调整大小?

‘&T as *const T as *mut T’ 在 ‘static mut’ 项目中合适吗?

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

如何判断服务器是否正确接收数据

是否可以预测堆栈溢出?

If let expression within .iter().any

为什么这个闭包没有比 var 长寿?

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

当值是新类型包装器时,对键的奇怪 HashMap 生命周期要求