我有以下代码(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
}

在我看来,这似乎应该编译为foobar有相同的签名:fn(u32) -> bool.然而,我得到了以下错误:

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}`

此代码可能会触发相同的错误:

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

我还try 再次将bar转换为函数指针类型:

let mut x = foo;
x = bar as fn(u32) -> bool;  // <-- 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`

我完全不理解这些错误.What are fn items vs. fn pointers and why are 100 and 101 different fn items?

推荐答案

Rust PR #19891合并以来,每个命名函数都有一个不同的类型.但是,可以使用as运算符将函数强制转换为相应的函数指针类型.

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

仅强制转换第一个函数也是有效的:强制转换将在第二个函数上进行推断,因为两个函数必须具有相同的类型.

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

Rust相关问答推荐

as操作符如何将enum转换为int?

在Tauri中获取ICoreWebView 2_7以打印PDF

rust 迹-内存管理-POP所有权-链表

MPSC频道在接收器处阻塞

为什么我们需要std::thread::scope,如果我们可以使用thread.join()在函数的生命周期内删除引用?

如何在Rust中将选项<;选项<;字符串>;转换为选项<;选项&;str>;?

获取已知数量的输入

装箱特性如何影响传递给它的参数的生命周期 ?(举一个非常具体的例子)

为什么 `Deref` 没有在 `Cell` 上实现?

为什么实现特征的对象期望比具体对象有更长的生命周期?

要求类型参数有特定的大小?

带引脚和不带引脚的比较功能

Google chrome 和 Apple M1 中的计算着色器

在 Rust 中使用 `SecTrustSettingsSetTrustSettings` 绑定导致 `errSecInternalComponent`

在 Rust 中,Weak 如何知道内部值何时被删除?

Rust 引用元组和引用元组

为什么这个值在上次使用后没有下降?

如何将 u8 切片复制到 u32 切片中?

C++ 中的 CRTP 是一种表达其他语言中特征和/或 ADT 的方法吗?

如何在 Rust 的泛型函​​数中同时使用非拥有迭代器和消费迭代器?