2017-07-01 70 views
-1

我有類似下面的代碼:「太多的參數」上完全正常的功能

pub trait WorldImpl { 
    fn new(size: (usize, usize), seed: u32) -> World; 
    fn three() -> bool; 
    fn other() -> bool; 
    fn non_self_methods() -> bool; 
} 
pub type World = Vec<Vec<UnitOfSpace>>; 
// I'm doing this because I want a SPECIAL version of Vec<Vec<UnitOfSpace>>, so I can treat it like a struct but have it be a normal type underneath. 
impl WorldImpl for World { 
    fn new(size: (usize, usize), seed: u32) -> World { 
    // Code 
     vec![/* vector stuff */] 
    } 
    // Implement other three methods 
} 
let w = World::new((120, 120), /* seed from UNIX_EPOCH stuff */); 

而且我得到這個錯誤,這顯然是錯誤的:

error[E0061]: this function takes 0 parameters but 2 parameters were supplied 
    --> src/main.rs:28:28 
    | 
28 |  let world = World::new((120 as usize, 120 as usize), 
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 0 parameters 

我想兩件事情:

  1. 這不是慣用的,Rust從來沒有用過這種方式。在這種情況下,我需要知道如何真正做到這一點。

  2. 這是一個愚蠢的錯誤,我錯過了。

當我在操場上嘗試類似上面的代碼時,它工作得很好,沒有錯誤。我還沒有找到任何其他地方的任何錯誤信息,所以我不會驚訝地發現我只是使用錯誤的語言。我對我的任何代碼都沒有特別的依戀,所以請告訴我這個成語是什麼!

回答

3

你試圖做的事情不太合理。您已將World作爲Vec<Vec<UnitOfSpace>>的類型別名,因此它們完全可以互換 - 您爲一個添加的實現將適用於另一個,反之亦然。

如果你想以不同方式對待這種類型,然後把它包在NEWTYPE:

struct World(Vec<Vec<UnitOfSpace>>); 

現在這是從Vec<Vec<UnitOfSpace>>的獨特的類型,但與零運行時開銷。

你實際的錯誤是因爲你已經添加了一個名爲newWorld作爲其實現的WorldImpl的一部分的方法,但World是已經具有new方法Vec(零ARGS!)。

+0

哦。啊。 *捂臉* –

1

您的類型WorldVec<Vec<UnitOfSpace>>的別名。 Vec<T>提供了一個固有的相關函數,稱爲new,它不帶任何參數。編譯器傾向於選擇固有的相關函數來定義特徵中的相關函數,因此它會選擇不帶參數的固有new,而不是您自己的帶有2個參數的new

下面是解決這幾個選項:

  1. 調用性狀的相關明確的功能:

    let w = <World as WorldImpl>::new((120, 120), /* seed from UNIX_EPOCH stuff */); 
    
  2. World一個NEWTYPE(struct World(Vec<Vec<UnitOfSpace>>);),這將讓你定義的內在關聯功能(但Vec的固有方法將不會在World)。

  3. WorldImpl::new重命名爲Vec上的固有關聯函數未使用的名稱。

+0

他們也可以改變'WorldImpl :: new'的名字。 –

+0

不是OP,但是你有鏈接可能會詳細說明爲什麼Rust更喜歡固有的fn而不是由於這種情況下的重複導致的錯誤? – loganfsmyth

+0

@loganfsmyth:沒有鏈接,但從我記得的推論是,如果它*沒有*做到這一點,那麼將會導致新的標準特徵(或添加現有特徵的方法)變得不可能。新的特徵和/或方法可能會影響人類類型的固有方法,破壞現有的代碼。 –