Option<impl Fn(i64)> [duplicate] 的 Rust 空显式通用参数

Rust empty explicit generic argument for Option<impl Fn(i64)> [duplicate]

提问人:Bitcoin Eagle 提问时间:8/4/2023 最后编辑:cafce25Bitcoin Eagle 更新时间:8/4/2023 访问量:58

问:

我有一个函数的参数,我想传递值。.如何正确编写函数调用以便编译?Option<impl Fn(i64) -> i64>apply()Noneapply(None)apply(None)

fn main(){
    let a = apply(Some(|i| i + 1));
    
    let b = apply(None);
    let b2 = apply(None::<dyn Fn(i64) -> i64>);
    
    println!("a: {0}; b: {1}", a, b)
}

fn apply(f: Option<impl Fn(i64) -> i64>) -> i64 {
    let i = 0_i64;
    match f {
        Some(f) => f(i),
        None => i,
    }
}

编译错误:

Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed
 --> src/main.rs:4:16
  |
4 |     let b = apply(None);
  |                   ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
  |
help: consider specifying the generic argument
  |
4 |     let b = apply(None::<T>);
  |                       +++++

error[E0283]: type annotations needed
  --> src/main.rs:4:16
   |
4  |     let b = apply(None);
   |             ----- ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
   |             |
   |             required by a bound introduced by this call
   |
   = note: multiple `impl`s satisfying `_: Fn<(i64,)>` found in the following crates: `alloc`, `core`:
           - impl<A, F> Fn<A> for &F
             where A: Tuple, F: Fn<A>, F: ?Sized;
           - impl<Args, F, A> Fn<Args> for Box<F, A>
             where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
note: required by a bound in `apply`
  --> src/main.rs:10:25
   |
10 | fn apply(f: Option<impl Fn(i64) -> i64>) -> i64 {
   |                         ^^^^^^^^^^^^^^ required by this bound in `apply`
help: consider specifying the generic argument
   |
4  |     let b = apply(None::<T>);
   |                       +++++

Some errors have detailed explanations: E0282, E0283.
For more information about an error, try `rustc --explain E0282`.

我试过了,但它仍然没有编译错误是let b2 = apply(None::<dyn Fn(i64) -> i64>);

 Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `dyn Fn(i64) -> i64` cannot be known at compilation time
 --> src/main.rs:5:20
  |
5 |     let b2 = apply(None::<dyn Fn(i64) -> i64>);
  |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `dyn Fn(i64) -> i64`
note: required by a bound in `None`
 --> /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/option.rs:567:5

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to previous error
泛型 Rust 闭包

评论

0赞 Unlikus 8/4/2023
不能在枚举中使用 trait 对象:users.rust-lang.org/t/why-doesn't-option-support-dyn-trait/45353/...
0赞 user2722968 8/4/2023
我不确定我是否正确回答了这个问题,但由于只需要任何给定签名的可调用类型,因此就足够了。所以语法是(注意 )。也就是说,的 -Value 是对动态类型的(大小)引用,该动态类型是给定签名的可调用对象。apply&dyn Fn(i64) -> i64apply(None::<&dyn Fn(i64) -> i64>)&NoneOption

答:

3赞 PitaJ 8/4/2023 #1

该类型是未调整大小的,这意味着您不能将其存储在 这样的枚举中。dyn Fn(i64) -> i64Option

但是特征对象引用的大小是确定的,因此您可以改用:&dyn

apply(None::<&dyn Fn(i64) -> i64>);

但是,最好改用函数指针类型:

apply(None::<fn(i64) -> i64>);

操场

评论

0赞 Bitcoin Eagle 8/7/2023
我根本不知道函数指针,到目前为止我只看到了三个特征,......。谢谢 🙂 。我想区别在于函数指针是简单的单指针,而 dyn Fn 是一个胖双指针,对吗?Fn
1赞 PitaJ 8/7/2023
是的,你明白了。