2015-10-17 15 views
7

Bu davranışı göstermek için Basit bir programı:Kutu <T> için neden özellik Fn() ile çakışıyor?

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); 
} 

Derleme başarısız:

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 

Sorularım şunlardır:

  1. As far as I can tellBox<T>

    Fn() özellik uygulamaz. O zaman neden yukarıdaki örnek başarısız?
  2. Yapmaya çalıştığım şeyin doğru uygulanması nedir?

Sadece Rust'u öğrenmeye başladım. Yardım ettiğin için teşekkür ederim. o TFn() uygulayan CanSpeak ve Box<T> uygulanması için bir tip Box<T> içinmümkündür çünkü

cevap

6

iki, çatışmayı yok. Pas uyumluluk kuralları, 'un olduğu, ancak 'un arasında ne olacağıyla ilgili değildir. İşte

sizin iki genel özellik uygulamalarını izin eğer net şeyler patlayacağını Box<Cow> için Fn() uygulayan bir örnek verilmiştir: Cevabınız için

// (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, _:()) { } 
} 
+2

Teşekkür Chris, ama hala alamadım Korkarım . Bu durumda 'Box'u özel yapan şeyin, Rust'un çatışabileceğini düşündüğü şeyi açıklayabilir misiniz? Örneğin, açıklamalarınızı doğru bir şekilde anladım, herhangi bir kapsayıcı, 'Arc ' da, 'T' CanSpeak 've 'Arc ' Fn() 'yi uygulayabildiği için çakışmalıdır. Ama '' Box' ı yerine benim örneğimde 'Arc' ile çalışmak gayet iyi çalışıyor. – Vikas

+3

Burada * özel * bir şey yok. Öte yandan, üst üste gelebilecek bir özellik için iki genel uygulama sağladınız. –

+0

O zaman neden Arc çalışıyor? Benim örneğimde 'Box'' 'Arc' ile değiştirirsem hata yapmadan derler. – Vikas

İlgili konular