简体   繁体   中英

Return &str instead of std::borrow::Cow<'_, str>

I want to update the variable input which is of type &str . How can I make the inner function return the &str instead of the Cow ?

This may be not a problem with the language but with the regex-crate. Is there one that is more straightforward?

fn transform_the_expression() {

    fn create_formula<'t>(input: &'t str, re: Regex) -> std::borrow::Cow<'t, str> {
        let changed_string = re.replace(input, "1");
        return changed_string;
    }

    let mut input = "(a+(b*c))";
    use regex::Regex;
    let re = Regex::new(r"\([\w\d][/*+-^][\w\d]\)").unwrap();

    println!("input = {:?}", input);
    input = create_formula(input, re);
    println!("input = {:?}", input);
}

You cannot .


The cornerstone of Rust is ownership , which is a concept you need to understand.

A &str borrows but does not own , it refers to a piece of memory that someone else owns. The borrow-checker will ensure, at compile-time, that whoever owns the piece of memory that is referred to will live longer than &str , as otherwise &str would point into the ether.

In this case, think of:

  • String being a cat
  • &str being a hand-held device running a live-feed of this cat (which is followed by a tiny camera drone)

Obviously, you can only have a live-feed of the cat as long as it lives , after that, ...

And your question is asking:

If I kill the cat, how do I still get a live-feed?

You cannot.


In your case, re.replace creates a Cow<'t, str> . If you look at the definition of Cow you'll notice that it is:

  • either a &str
  • or a String

It is a &str only if no replacement occurred, and otherwise it is a String .

You cannot know, statically, which it is, so you need to consider the "worst case" alternative: think of it as a String .

What's the lifetime of this String : it depends whether you return it from the function or not, if you don't, it cannot outlive the function's frame.

And if it doesn't outlive the function frame, you cannot have a live-feed that outlive the function frame.


So?

My advice is to use a String . It'll be vastly simpler:

fn transform_the_expression() {
    use regex::Regex;

    fn create_formula(input: &str, re: &Regex) -> String {
        re.replace(input, "1").into()
    }

    let mut input = String::from("(a+(b*c))");
    let re = Regex::new(r"\([\w\d][/*+-^][\w\d]\)").unwrap();

    println!("input = {:?}", input);
    input = create_formula(&input, &re);
    println!("input = {:?}", input);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM