2015-10-29 26 views
3

我有一個函數來清理字符串,看起來是這樣的:回到原始的或修改後的字符串

fn clean(s: &str) -> &str { // but not sure about return type 
    if /* needs cleaning */ { 
     let cleaned: String = s.chars().filter(/* etc */).collect(); 
     cleaned 
    } else { 
     s 
    } 
} 

除非這樣寫是不行的,因爲清洗是String,不是&str

這裏的目標是僅在必要時執行分配 - 如果字符串需要修改,我想用新的替換它,如果不需要,我不想致電to_string()它。理想情況下,我希望對調用者透明,但不一定非要 - 我也可以控制調用代碼。即使如此,我還沒有找到解決方法,因爲如果新創建的String,或者甚至借用它,最終以調用者的某種if或else塊的形式出現,則它的壽命不足以用於否則使用原始字符串的上下文。例如,這也不起作用:

fn caller(s: &str) { 
    if needs_cleaning(s) { 
     let cleaned = clean(s); // where clean always returns a new String 
     s = &cleaned; 
    } 

    /* do stuff with the clean string */ 
} 

這裏有什麼正確的方法?

回答

9

您正在尋找Cow

use std::borrow::Cow; 

fn clean(s: &str) -> Cow<str> { 
    if /* needs cleaning */ { 
     let cleaned: String = s.chars().filter(/* etc */).collect(); 
     Cow::Owned(cleaned) 
    } else { 
     Cow::Borrowed(s) 
    } 
} 
+1

你也可以寫只是'cleaned.into()'和's.into()',而不是因爲這兩個'String'和'明確命名的枚舉變量&str'執行'進入>'。 –

+0

謝謝!我以爲我看到過類似的東西,然後不記得它叫什麼,或者當我找到它時再次找到它。 – David