为什么对实现Fn的类型的引用不能被识别为可调用的



即使&T被定义为实现Fn特性,编译器在调用它时也会拒绝它

trait Trait {
fn act(self);
}
//passes
fn test_ref_input_as_trait<'a, T>(t: &'a T)
where
&'a T: Trait,
{
t.act();
}
//fails
fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
where
&'a T: Fn(),
{
t();
}
//passes
fn test_input_as_fntrait<T>(t: T)
where
T: Fn(),
{
t();
}

编译器拒绝第二个函数的定义:

error[E0618]: expected function, found `&'a T`
--> src/lib.rs:18:5
|
14 | fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
|                                     - `&'a T` defined here
...
18 |     t();
|     ^^^ not a function

对于夜间(1.32(,错误消息替换为:

error[E0618]: expected function, found `&'a T`
--> src/lib.rs:18:5
|
14 | fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
|                                     - `&'a T` defined here
...
18 |     t();
|     ^--
|     |
|     call expression requires function

也许我遗漏了一些东西,但为什么编译器接受定义但不允许调用它?是不是我的语法缺陷导致它理解了其他东西?

有一个悬而未决的问题(#42736(。但是,Fn的文档状态为:

对于实现Fn的任何类型的F&F也实现Fn

这意味着以下操作有效:

fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
where
T: Fn(),
{
t();
}

这可能是一个错误(例如,如果用(&'a T,)替换&'a T,它会起作用(。尽管如此,您可以这样调用函数:

fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
where
&'a T: Fn(),
{
(&t)();
}

但是由于T: Fn()会自动暗示&T: Fn(),所以像上一个例子一样写会更容易,也更习惯。

fn test_ref_input_as_fntrait<F: Fn()>(t: F) {
t();
}
fn main() {
test_ref_input_as_fntrait(&|| println!("it's okay!"));
}

相关内容

  • 没有找到相关文章

最新更新