Generics 为什么对Box<;T>;与Fn()冲突?

Generics 为什么对Box<;T>;与Fn()冲突?,generics,rust,traits,Generics,Rust,Traits,演示此行为的简化程序: use std::boxed::Box; struct Cow; trait CanSpeak { fn speak(&self); } impl CanSpeak for Cow { fn speak(&self) { println!("moo"); } } impl<F: Fn()> CanSpeak for F { fn speak(&self) { sel

演示此行为的简化程序:

use std::boxed::Box;

struct Cow;

trait CanSpeak {
    fn speak(&self);
}

impl CanSpeak for Cow {
    fn speak(&self) {
        println!("moo");
    }
}

impl<F: Fn()> CanSpeak for F {
    fn speak(&self) {
        self();
    }
}

impl<T: CanSpeak> CanSpeak for Box<T> {
    fn speak(&self) {
        (**self).speak()
    }
}

fn lol_speak() {
    println!("lol")
}

fn lets_speak<T: CanSpeak>(t: & T) {
    t.speak();
}

fn main() {
    let cow = Cow;
    lets_speak( &cow );

    lets_speak( &lol_speak );

    let boxed_cow = Box::new(Cow);
    lets_speak( &boxed_cow );
}
使用std::boxed::Box;
结构牛;
我会说话{
fn说话(和自我);
}
我能为母牛说话吗{
fn讲话(自我){
println!(“moo”);
}
}
impl可以代表F{
fn讲话(自我){
self();
}
}
impl可以为Box说话{
fn讲话(自我){
(**self.speak()
}
}
fn lol_speak(){
println!(“lol”)
}
fn让你说话(t:&t){
t、 说();
}
fn main(){
让牛=牛;
让我们说话(牛);
让你说话(&lol\u说话);
让装箱的牛=箱子::新的(牛);
让我们说话(和装箱的牛);
}
编译失败,原因是:

test.rs:15:1: 19:2 error: conflicting implementations for trait `CanSpeak` [E0119]
test.rs:15 impl<F: Fn()> CanSpeak for F {
test.rs:16     fn speak(&self) {
test.rs:17         self();
test.rs:18     }
test.rs:19 }
test.rs:15:1: 19:2 help: run `rustc --explain E0119` to see a detailed explanation
test.rs:21:1: 25:2 note: note conflicting implementation here
test.rs:21 impl<T: CanSpeak> CanSpeak for Box<T> {
test.rs:22     fn speak(&self) {
test.rs:23         (**self).speak()
test.rs:24     }
test.rs:25 }
error: aborting due to previous error
test.rs:15:1:19:2错误:trait`CanSpeak`[E0119]的实现冲突
测试:15个impl可以代表F{
测试。rs:16 fn口语(和自我){
测试rs:17个self();
test.rs:18}
test.rs:19}
test.rs:15:1:19:2帮助:运行'rustc--explain E0119'查看详细说明
test.rs:21:1:25:2注意:注意这里的实现冲突
测试。rs:21 impl可以为Box说话{
测试。rs:22 fn口语(和自我){
test.rs:23(**self).speak()
test.rs:24}
test.rs:25}
错误:由于上一个错误而中止
我的问题是:

  • Box
    未实现
    Fn()
    trait。那么为什么上面的例子失败了呢
  • 我要做的事情的正确实现是什么

  • 我刚开始学生锈。感谢您的帮助。

    这两种方法确实存在冲突,因为类型
    Box
    可能有
    T
    实现
    CanSpeak
    Box
    实现
    Fn()
    。规则不是关于什么是,而是关于什么可以是

    下面是一个为
    Box
    实现
    Fn()
    的示例,如果它允许两个通用的trait实现,那么显然会发生爆炸:

    // (This attribute on the crate.)
    #![feature(unboxed_closures, core)]
    
    impl Fn<()> for Box<Cow> {
        extern "rust-call" fn call(&self, _: ()) { }
    }
    
    impl FnMut<()> for Box<Cow> {
        extern "rust-call" fn call_mut(&mut self, _: ()) { }
    }
    
    impl FnOnce<()> for Box<Cow> {
        type Output = ();
        extern "rust-call" fn call_once(self, _: ()) { }
    }
    
    //(板条箱上的此属性。)
    #![特征(未固定的_闭合,核心)]
    适用于盒子的impl Fn{
    外部“锈调用”fn调用(&self,:()){}
    }
    框的impl FnMut{
    外部“锈调用”fn调用{mut(&mut self,{}
    }
    一次装盒{
    类型输出=();
    外部“锈调用”fn调用一次(self,\()){
    }
    
    谢谢克里斯的回复,但恐怕我还是没有收到。你能解释一下在这种情况下,
    Box
    有什么特别之处,Rust认为它会发生冲突吗?例如,如果我正确理解您的解释,任何容器,比如说
    Arc
    也应该冲突,因为
    T
    可以实现
    CanSpeak
    ,而
    Arc
    可以实现
    Fn()
    。但是在我的示例中,用
    Arc
    替换
    Box
    效果很好,没有什么特别之处。只是您为一个可能重叠的特性提供了两个通用实现。那么为什么
    Arc
    可以工作呢?在我的示例中,如果我用
    Arc
    替换
    Box
    ,它编译时没有任何错误。Box是特殊的,它被标记为
    #[基本]
    (而Arc不是)。确切的规则是什么,我现在还不知道。哦,不,下一个难题是:
    Fn
    特征也被标记为
    #[基本]
    ,它也很特别!正确的灌木丛!使用不同的边界,它将发生冲突。