2015-10-29 27 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