为什么对实现 Fn 的类型的引用不被识别为可调用?
Why is a reference to a type that implements Fn not recognized as a callable?
即使 &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
对于 nightly (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
也许我遗漏了什么,但为什么编译器接受定义但不允许调用它?是我这边的句法缺陷导致它理解别的东西吗?
这可能是一个错误(例如,如果您将 &'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!"));
}
有一个open issue (#42736) about this. However, the docs for Fn
状态:
for any type F
that implements Fn
, &F
implements Fn
, too.
这意味着以下工作:
fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
where
T: Fn(),
{
t();
}
即使 &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
对于 nightly (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
也许我遗漏了什么,但为什么编译器接受定义但不允许调用它?是我这边的句法缺陷导致它理解别的东西吗?
这可能是一个错误(例如,如果您将 &'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!"));
}
有一个open issue (#42736) about this. However, the docs for Fn
状态:
for any type
F
that implementsFn
,&F
implementsFn
, too.
这意味着以下工作:
fn test_ref_input_as_fntrait<'a, T>(t: &'a T)
where
T: Fn(),
{
t();
}