我有一个函数来清理看起来像这样的字符串:
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块中结束,那么它就会被解决。 s的生命周期不足以在使用原始字符串的上下文中使用。例如,这也不起作用:
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 */
}
这里有什么正确的方法?
答案 0 :(得分: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)
}
}