即使&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!"));
}