2015-09-24 49 views
5

在Rust中,在編寫具有特性的模塊時,我傾向於遇到設計問題。我並不總是知道我是否要:默認特徵方法和參數化函數之間有什麼區別?

pub trait Foo { 
    fn foo(&self) -> bool; 

    fn bar(&self) { 
     if self.foo() { 
      // Do something! 
     } else { 
      // Do something else! 
     } 
    } 
} 

或者

pub trait Foo { 
    fn foo(&self) -> bool; 
} 

pub fn bar<T>(fooer: &T) where T: Foo { 
    if fooer.foo() { 
     // Do something! 
    } else { 
     // Do something else! 
    } 
} 

(當然,實際的例子可能有更復雜的特性或功能簽名)

而設計的問題超出Stack Overflow的範圍,我不完全確定我甚至明白了兩者之間有意義的,客觀的差異,並且我不覺得瀏覽標準庫已經流光溢彩。它似乎似乎像Rust的標準庫更喜歡使用variable.method()而不是mod::function(&variable)在大多數情況下。但是,這仍然沒有真正回答這個問題,因爲這只是一種風格指導的論點,而不是基於對差異的客觀認識。

除了明顯的語法差異之外,缺省特徵方法和模塊級參數化函數之間的主要區別是什麼?我有一個很大的問題是:默認的trait方法monomorphize使用靜態調度,還是如果它需要self就好像它是一個特質對象?

我看到的唯一區別就是該特徵的impl可能會選擇重寫默認方法實現,希望/假設提供的實現滿足相同的合同,而我保證mod::function實現始終運行完全相同的代碼,無論(好或壞)。還有別的事嗎?如果涉及到相關類型或擴展特徵,答案是否會改變?

回答

4

你其實自己回答了這個問題,恭喜!

由於Rust只通過特徵有原理性的重載/覆蓋,所以基本的語義差異是可以覆蓋特徵method,並因此自定義,而自由函數不能。

從技術上講,Trait::func(&self)mod::func<T: Trait>(&T)都monophormized而mod::func(&Trait)不(因此會招致虛擬通話的輕微開銷)。內存開銷爲Trait::func(&self):在虛擬表中還有一項。這可能不明顯。

總的來說,這個選擇通常是一個判斷呼叫。無論您是否打開定製門,都​​是您的選擇。

相關問題