Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

string

rust

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);
}
like image 872
J. Dough Avatar asked Feb 15 '17 11:02

J. Dough


People also ask

What is a return in finance?

Return Explained A return (also referred to as a financial return or investment return) is usually presented as a percentage relative to the original investment over a given time period. There are two commonly used rates of return in financial management. Nominal rates of return that include inflation.

What is making a return?

A retail return occurs when a customer brings purchased items back to a retailer in exchange for refund, store credit, or similar item.

Is being returned Meaning?

having come back from somewhere, or having been sent back: Recently returned from five years in Paris, he set up a business in London. Returned prisoners sometimes found that their troubles continued after they reached home.


1 Answers

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);
}
like image 84
Matthieu M. Avatar answered Oct 06 '22 02:10

Matthieu M.