返回原始或修改的字符串

Dav*_*vid 3 rust

我有一个函数来清理看起来像这样的字符串:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

除了这不起作用,因为清理是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 */
}
Run Code Online (Sandbox Code Playgroud)

这里有什么正确的方法?

Ste*_*ven 10

你在寻找:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您还可以只编写 `cleaned.into()` 和 `s.into()` 而不是显式命名枚举变体,因为 `String` 和 `&amp;str` 都实现了 `Into&lt;Cow&lt;str&gt;&gt;`。 (2认同)