Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

rust - "Expected fn item, found a different fn item" when working with function pointers

I have the following code (Playground):

// Two dummy functions, both with the signature `fn(u32) -> bool`
fn foo(x: u32) -> bool {
    x % 2 == 0
}
fn bar(x: u32) -> bool {
    x == 27
}


fn call_both<F>(a: F, b: F)
where
    F: Fn(u32) -> bool,
{
    a(5);
    b(5);
}

fn main() {
    call_both(foo, bar);  // <-- error
}

To me, it seems like this should compile as foo and bar have the same signature: fn(u32) -> bool. Yet, I get the following error:

error[E0308]: mismatched types
  --> src/main.rs:20:20
   |
20 |     call_both(foo, bar);
   |                    ^^^ expected fn item, found a different fn item
   |
   = note: expected type `fn(u32) -> bool {foo}`
              found type `fn(u32) -> bool {bar}`

The same error can be triggered with this code:

let mut x = foo;
x = bar;  // <-- error

I also tried to cast bar to the function pointer type again:

let mut x = foo;
x = bar as fn(u32) -> bool;  // <-- error

This resulted in a slightly different error:

error[E0308]: mismatched types
  --> src/main.rs:20:9
   |
20 |     x = bar as fn(u32) -> bool;
   |         ^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
   |
   = note: expected type `fn(u32) -> bool {foo}`
              found type `fn(u32) -> bool`

I don't understand these errors at all. What are fn items vs. fn pointers and why are foo and bar different fn items?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Each named function has a distinct type since Rust PR #19891 was merged. You can, however, cast the functions to the corresponding function pointer type with the as operator.

call_both(foo as fn(u32) -> bool, bar as fn(u32) -> bool);

It's also valid to cast only the first of the functions: the cast will be inferred on the second, because both functions must have the same type.

call_both(foo as fn(u32) -> bool, bar);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...