无法 return a Vec<Box<dyn Fn(f32) -> f32>>

Unable to return a Vec<Box<dyn Fn(f32) -> f32>>

我正在尝试 return 来自 Rust 函数的闭包向量。其中每一个最终都将存储在一个包含 Box<dyn Fn(f32) -> f32> 的结构中。这是错误的简单再现:

fn something() -> Vec<Box<dyn Fn(f32) -> f32>> {
    let mut vec = Vec::new();

    for i in 0..5 {
        vec.push(
            Box::new(
                |t : f32| { t + 1.0 }
            )
        );
    }

    vec
}
error[E0308]: mismatched types
  --> src\main.rs:13:5
   |
2  | fn something() -> Vec<Box<dyn Fn(f32) -> f32>> {
   |                   ---------------------------- expected `Vec<Box<(dyn Fn(f32) -> f32 + 'static)>>` because of return 
type
...
8  |                 |t : f32| { t + 1.0 }
   |                 --------------------- the found closure
...
13 |     vec
   |     ^^^ expected trait object `dyn Fn`, found closure
   |
   = note: expected struct `Vec<Box<(dyn Fn(f32) -> f32 + 'static)>>`
              found struct `Vec<Box<[closure@src\main.rs:8:17: 8:38]>>`

鉴于提供的闭包实现了所需的特征,我不明白这个错误及其来源。我是 Rust 的新手,在闭包方面遇到了很大的困难。

您的 google-fu 需要更多爵士乐:

答案是替换这一行:

let mut vec = Vec::new();

有了这个:

let mut vec: Vec<Box<dyn Fn(f32) -> f32>> = Vec::new();

因为您已经明确告诉编译器 Vec 应该是什么,所以它会正确运行,否则它只会采用添加的第一个元素的类型。链接的问题对此进行了更多解释。将该变量指定为函数中的 return 不足以将其绑定到函数的 return 类型。

发生这种情况是因为在推断 Vec 的类型时,您指定的闭包的具体类型优先于 return 类型。换句话说,由于闭包本身 |t : f32| { t + 1.0 } 有一个匿名但 具体 类型,它被推断为 Vec.[=19= 的类型]

这可以通过明确指定类型来解决:

let mut vec: Vec<Box<dyn Fn(f32) -> f32>> = Vec::new();

或者,通过告诉编译器我们仍然不知道类型,让它然后从return类型推断:

vec.push(
    Box::new(
        |t : f32| { t + 1.0 }
    ) as Box<_>
);

注意添加的 as Box<_>.

作为一般的经验法则,Rust 可能能够正确地推断出类型,只是它的推断规则有时会告诉它坚持最早的具体类型。当你遇到像这样的障碍时,只需尝试在 as Box<_> 或其他方式(如 as _as Arc<_> 等)。