Rust 中的空泛型参数用于 Option

huangapple go评论144阅读模式
英文:

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

问题

The code you provided is in Rust, and it seems like you're encountering type inference issues when trying to call the apply(None) function. Here's a possible solution:

  1. fn main() {
  2. let a = apply(Some(|i| i + 1));
  3. let b = apply(None::<fn(i64) -> i64>);
  4. println!("a: {}; b: {}", a, b);
  5. }
  6. fn apply(f: Option<impl Fn(i64) -> i64>) -> i64 {
  7. let i = 0_i64;
  8. match f {
  9. Some(f) => f(i),
  10. None => i,
  11. }
  12. }

In the revised code, I specified the generic type parameter for None as None::<fn(i64) -> i64>, which should help the Rust compiler infer the type correctly.

英文:

I have Option&lt;impl Fn(i64) -&gt; i64&gt; as an argument to a function apply() and I want to pass None value. apply(None). How do I write the apply(None) function call correctly so it compiles?

  1. fn main(){
  2. let a = apply(Some(|i| i + 1));
  3. let b = apply(None);
  4. let b2 = apply(None::&lt;dyn Fn(i64) -&gt; i64&gt;);
  5. println!(&quot;a: {0}; b: {1}&quot;, a, b)
  6. }
  7. fn apply(f: Option&lt;impl Fn(i64) -&gt; i64&gt;) -&gt; i64 {
  8. let i = 0_i64;
  9. match f {
  10. Some(f) =&gt; f(i),
  11. None =&gt; i,
  12. }
  13. }

compile error:

  1. Compiling playground v0.0.1 (/playground)
  2. error[E0282]: type annotations needed
  3. --&gt; src/main.rs:4:16
  4. |
  5. 4 | let b = apply(None);
  6. | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
  7. |
  8. help: consider specifying the generic argument
  9. |
  10. 4 | let b = apply(None::&lt;T&gt;);
  11. | +++++
  12. error[E0283]: type annotations needed
  13. --&gt; src/main.rs:4:16
  14. |
  15. 4 | let b = apply(None);
  16. | ----- ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
  17. | |
  18. | required by a bound introduced by this call
  19. |
  20. = note: multiple `impl`s satisfying `_: Fn&lt;(i64,)&gt;` found in the following crates: `alloc`, `core`:
  21. - impl&lt;A, F&gt; Fn&lt;A&gt; for &amp;F
  22. where A: Tuple, F: Fn&lt;A&gt;, F: ?Sized;
  23. - impl&lt;Args, F, A&gt; Fn&lt;Args&gt; for Box&lt;F, A&gt;
  24. where Args: Tuple, F: Fn&lt;Args&gt;, A: Allocator, F: ?Sized;
  25. note: required by a bound in `apply`
  26. --&gt; src/main.rs:10:25
  27. |
  28. 10 | fn apply(f: Option&lt;impl Fn(i64) -&gt; i64&gt;) -&gt; i64 {
  29. | ^^^^^^^^^^^^^^ required by this bound in `apply`
  30. help: consider specifying the generic argument
  31. |
  32. 4 | let b = apply(None::&lt;T&gt;);
  33. | +++++
  34. Some errors have detailed explanations: E0282, E0283.
  35. For more information about an error, try `rustc --explain E0282`.

I tried let b2 = apply(None::&lt;dyn Fn(i64) -&gt; i64&gt;); but it still doesn't compile the errors are

  1. Compiling playground v0.0.1 (/playground)
  2. error[E0277]: the size for values of type `dyn Fn(i64) -&gt; i64` cannot be known at compilation time
  3. --&gt; src/main.rs:5:20
  4. |
  5. 5 | let b2 = apply(None::&lt;dyn Fn(i64) -&gt; i64&gt;);
  6. | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn&#39;t have a size known at compile-time
  7. |
  8. = help: the trait `Sized` is not implemented for `dyn Fn(i64) -&gt; i64`
  9. note: required by a bound in `None`
  10. --&gt; /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/option.rs:567:5
  11. For more information about this error, try `rustc --explain E0277`.
  12. error: could not compile `playground` (bin &quot;playground&quot;) due to previous error

答案1

得分: 3

The type dyn Fn(i64) -> i64 is unsized, meaning you can't store it in an enum like Option.

But a trait object reference is sized, so you can use &dyn instead:

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

However, it's probably better to use a function pointer type instead:

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

playground

英文:

The type dyn Fn(i64) -&gt; i64 is unsized, meaning you can't store it in an enum like Option.

But a trait object reference is sized, so you can use &amp;dyn instead:

  1. apply(None::&lt;&amp;dyn Fn(i64) -&gt; i64&gt;);

However, it's probably better to use a function pointer type instead:

  1. apply(None::&lt;fn(i64) -&gt; i64&gt;);

playground

huangapple
  • 本文由 发表于 2023年8月4日 22:06:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76836692.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定