2014-08-29 39 views
0

當我在Rust中的一個結構體上實現一個特性時,它導致找不到struct類型。首先,工作代碼:實現Rust特性導致struct不被發現

trait SomeTrait { 
    fn new() -> Box<SomeTrait>; 
    fn get_some_value(&self) -> int; 
} 

struct SomeStruct { 
    value: int 
} 

impl SomeStruct { 
    fn new() -> Box<SomeStruct> { 
    return box SomeStruct { value: 3 }; 
    } 

    fn get_some_value(&self) -> int { 
    return self.value; 
    } 
} 

fn main() { 
    let obj = SomeStruct::new(); 
    println!("{}", obj.get_some_value()); 
} 

這裏的SomeTrait特質沒有被使用。一切正常。如果我現在改變SomeStruct的IMPL實施SomeTrait:

trait SomeTrait { 
    fn new() -> Box<SomeTrait>; 
    fn get_some_value(&self) -> int; 
} 

struct SomeStruct { 
    value: int 
} 

impl SomeTrait for SomeStruct { 
    fn new() -> Box<SomeTrait> { 
    return box SomeStruct { value: 3 }; 
    } 

    fn get_some_value(&self) -> int { 
    return self.value; 
    } 
} 

fn main() { 
    let obj = SomeStruct::new(); 
    println!("{}", obj.get_some_value()); 
} 

我得到的錯誤:

trait.rs:21:13: 21:28 error: failed to resolve. Use of undeclared module `SomeStruct` 
trait.rs:21 let obj = SomeStruct::new(); 
         ^~~~~~~~~~~~~~~ 
trait.rs:21:13: 21:28 error: unresolved name `SomeStruct::new`. 
trait.rs:21 let obj = SomeStruct::new(); 

我在做什麼錯?爲什麼SomeStruct突然失蹤?謝謝!

回答

1

目前,性狀中的相關功能(非方法功能)是通過性狀調用的,即SomeTrait::new()。然而,如果你只是寫這個,編譯器不能解決 impl你正在使用的,因爲沒有辦法指定SomeStruct信息(只有在簽名處提到特殊的Self類型時纔有效)。也就是說,編譯器需要能夠計算應該調用哪個版本的new。 (這是必需的,它們可以有非常不同的行爲:

struct Foo; 
impl SomeTrait for Foo { 
    fn new() -> Box<SomeTrait> { box Foo as Box<SomeTrait> } 
} 

struct Bar; 
impl SomeTrait for Bar { 
    fn new() -> Box<SomeTrait> { 
     println!("hello") 
     box Bar as Box<SomeTrait> 
    } 
} 

或者東西不僅僅是印刷更多的戲劇性。)

這是一種語言孔將由UFCS填補。就目前而言,你需要使用dummy- Self招:

trait SomeTrait { 
    fn new(_dummy: Option<Self>) -> Box<SomeTrait>; 
    ... 
} 

,然後將其稱爲像SomeTrait::new(None::<SomeStruct>)

但是,我質疑你爲什麼從構造函數返回一個盒裝對象。這是很少見一個好主意,它通常最好還是直接返回平原類型,並在必要時用戶可以框呢,那就是,

trait SomeTrait { 
    fn new() -> Self; 
    ... 
} 

(NB。此簽名提到Self,因此Option伎倆以上)


旁註:錯誤信息是相當糟糕的,但它只是反映了這些方法是如何實現的; impl Foo中的關聯函數與編寫mod Foo { fn ... }非常相似。你可以看到它通過強制編譯器創建的模塊不同:

struct Foo; 
impl Foo { 
    fn bar() {} 
} 

fn main() { 
    Foo::baz(); 
} 

版畫只是

<anon>:7:5: 7:13 error: unresolved name `Foo::baz`. 
<anon>:7  Foo::baz(); 
      ^~~~~~~~ 

Foo「模塊」的存在。