Rust 当闭包作为trait对象参数传递时,为什么需要强制转换?

Rust 当闭包作为trait对象参数传递时,为什么需要强制转换?,rust,closures,traits,Rust,Closures,Traits,我试图创建一个特性,它应该使用不同数量的参数抽象函数/闭包。大概是这样的: trait MyTrait {} impl MyTrait for Box<Fn() -> &'static str> {} impl MyTrait for Box<Fn(u8) -> u8> {} fn myf<F: MyTrait>(_fun: F) {} fn main() { myf(Box::new(|i: u8| i + 2)) }

我试图创建一个特性,它应该使用不同数量的参数抽象函数/闭包。大概是这样的:

trait MyTrait {}

impl MyTrait for Box<Fn() -> &'static str> {}

impl MyTrait for Box<Fn(u8) -> u8> {}
fn myf<F: MyTrait>(_fun: F) {}

fn main() {
    myf(Box::new(|i: u8| i + 2))
}
trait MyTrait{}
框的impl MyTrait&'static str>{}
框u8>{}的impl MyTrait
最初我打算这样使用它:

trait MyTrait {}

impl MyTrait for Box<Fn() -> &'static str> {}

impl MyTrait for Box<Fn(u8) -> u8> {}
fn myf<F: MyTrait>(_fun: F) {}

fn main() {
    myf(Box::new(|i: u8| i + 2))
}
fn myf(_-fun:F){}
fn main(){
myf(框:新(| i:u8 | i+2))
}
但此代码失败并出现错误:

error[E0277]:特性绑定'std::boxed::Box:MyTrait'不满足
当我像这样投射框时,所有内容都正确编译:

myf(Box::new(|i: u8| i + 2) as Box<Fn(_) -> _>)
myf(框::新(| i:u8 | i+2)作为框)


为什么Rust编译器不能在没有强制转换的情况下推断出这个特性?我的方法(使用cast)正确吗,还是有更简单的方法?我更喜欢为我的项目启用
trial\u casts
警告,这种语法会触发它。

人们往往会忘记这一点:每个闭包都是实现
Fn
的不同结构:
Fn
是一个特征,而不是一个结构,特征实现是不可传递的

这里有一个小例子说明了这一点:

trait Base {}
trait Derived {}
struct Foo {}

impl Base for Derived {}

impl Derived for Foo {}

fn myf<T>(_t: Box<T>)
where
    T: Base + ?Sized,
{
}

fn main() {
    let foo = Box::new(Foo {});
    //myf(foo) // does not compile
    myf(foo as Box<Derived>)
}
trait Base{}
性状衍生{}
结构Foo{}
派生{}的impl基
为Foo{}派生的impl
fn myf(\u t:Box)
哪里
T:基础+尺寸,
{
}
fn main(){
设foo=Box::new(foo{});
//myf(foo)//不编译
myf(foo as框)
}
你真正想做的是:

trait MyTrait {}

impl<T> MyTrait for T
where
    T: Fn() -> &'static str,
{
}

impl<T> MyTrait for T
where
    T: Fn(u8) -> u8,
{
}

fn myf<F>(_fun: Box<F>)
where
    F: MyTrait,
{
}

fn main() {
    myf(Box::new(|i: u8| i + 2))
}
trait MyTrait{}
为T
哪里
T:Fn()->&'static str,
{
}
为T
哪里
T:Fn(u8)->u8,
{
}
fn myf(_fun:Box)
哪里
F:我的特点,
{
}
fn main(){
myf(框:新(| i:u8 | i+2))
}
但这无法编译,因为存在两个冲突的实现