首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锈蚀车辆中部分&str的更换

锈蚀车辆中部分&str的更换
EN

Stack Overflow用户
提问于 2016-05-20 21:27:25
回答 1查看 1.7K关注 0票数 0

我编写了以下代码:

代码语言:javascript
复制
use std::str::{from_utf8};

struct JSONPointer {
    segments: Vec<String>
}

fn build_json_pointer(s: Vec<String>) -> JSONPointer {
    JSONPointer { segments: s.iter().map(|x| x.replace("~1", "/").replace("~0", "~")).collect() }
}

fn main() {
    let v = vec!["foo".to_string(), "bar".to_string(), "baz~1".to_string()];
    let p = build_json_pointer(v);

    println!("Hello world! {:?}", p.segments);
}

这一切都适用于String,但理想情况下,我的JSONPointer结构将包含一个Vec<&str> (如果只是为了学习目的)。我遇到的问题发生在对map的调用中,它替换了几个保留字符串。无论我使用的转换组合,我总是被告知我的borrowed value does not live long enough

据我所知,我引用了一个本地值,并试图返回它(导致一个可能的使用后删除错误),但我似乎找不到一种方法来获取字符串的副本。

编辑:更新为最小可复制形式

现在我意识到,当我指的是想要一个“副本”(堆分配的)时,这正是String。有人说要用一种更干净的方法来做这件事,尽管如此。

EN

回答 1

Stack Overflow用户

发布于 2016-05-21 00:41:38

如果您担心不必要地分配字符串,则有可能使用Cow

代码语言:javascript
复制
use std::borrow::Cow;

struct JSONPointer<'a> {
    segments: Vec<Cow<'a, str>>,
}

fn replace_if<'a>(s: Cow<'a, str>, from: &str, to: &str) -> Cow<'a, str> {
    if s.contains(from) {
        Cow::Owned(s.replace(from, to))
    } else {
        s
    }
}

fn build_json_pointer<'a>(s: &[&'a str]) -> JSONPointer<'a> {
    let segments = s
        .iter()
        .copied()
        .map(Cow::Borrowed)
        .map(|x| replace_if(x, "~1", "/"))
        .map(|x| replace_if(x, "~0", "~"))
        .collect();

    JSONPointer { segments }
}

fn main() {
    let v = vec!["foo", "bar", "baz~1"];
    let p = build_json_pointer(&v);

    println!("Hello world! {:?}", p.segments);
}

这样做的好处是,当不需要进行替换时,它不需要分配任何内存,但是缺点是每个模式都被搜索了两次。如果使用像这样的结构,它可能会更高效。

对于接受String的原始案例,您可以在不使用Cow的情况下执行类似的操作,方法是保留原始String,而不是无条件地替换它:

代码语言:javascript
复制
struct JSONPointer {
    segments: Vec<String>,
}

fn replace_if(s: String, from: &str, to: &str) -> String {
    if s.contains(from) {
        s.replace(from, to)
    } else {
        s
    }
}

fn build_json_pointer(s: &[String]) -> JSONPointer {
    let segments = s
        .iter()
        .cloned()
        .map(|x| replace_if(x, "~1", "/"))
        .map(|x| replace_if(x, "~0", "~"))
        .collect();

    JSONPointer { segments }
}

fn main() {
    let v = vec!["foo".to_string(), "bar".to_string(), "baz~1".to_string()];
    let p = build_json_pointer(&v);

    println!("Hello world! {:?}", p.segments);
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37356131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档