What's the best pattern for dealing with regex results?

I'm a Javascript developer looking for my own game with Rust. I have read The Rust Programming Language, completed the tutorials and successfully added Rust to a node project using FFI. I would like to speed up the parser I wrote, but I think I am missing the fundamental concept of ownership.

The current task is simple: evaluate the regex for the named capture and change the value of the variable to the new captured value.

I've tried this fifteen ways using unwrap

either nested Result

and Option

s. It always boils down to a "not long enough" error.

My final code looks like this:

let flag_re = compile_re(r"(?:\s*)([~])(?:\s*)(?P<FLAG>.)"); 

let mut flag : &str = "V";

for line in file.lines() {

    let mut current_line : String = line.unwrap();

    if flag_re.is_match(&current_line) {

        let new_flag = &flag_re.captures(&current_line).unwrap().name("FLAG").unwrap().clone();

        println!("old flag: {} new flag: {}",flag,new_flag);

        flag = new_flag;

    }

      

This works great if I comment out the line flag = new_flag

. But as soon as I try to assign a value flag

, I get a "not long enough" message in the variable current_line

. I get that current_line

short-lived, so I tried clone

with to_owned

no luck and convinced me to be sure I had some misunderstandings about the concepts.

I tried to recreate this in a Rust playground with this code:

fn main() {
   let mut a: &str;
   {
     let b: &str = "B";
     a = b;  
   }
   println!("a: {} ",a);
}

      

But (don't you know) it works? So please be careful with this Javascript guy.

+3


source to share


1 answer


The problem is that it is new_flag

borrowed from line

. That is, it new_flag

can exist only as long as it line

continues to exist. As soon as you exit the loop, it line

will be destroyed.

The simplest way to deal with this is to jump from a borrowed string ( &str

) to an owned string ( String

). That is, you need a value that owns its content so that there is no borrowing in the game. The corresponding changes will be as follows:



let mut flag = String::from("V"); // One way of constructing a String from a &str
...
    flag = new_flag.into(); // Another way, using inference

      

A slightly more efficient alternative would be to use std::borrow::Cow

, but this is probably not needed in this context.

+2


source







All Articles