Two functions treat mutable argument different


#1

at https://github.com/DaanHoogland/tr/blob/master/src/main.rs I have two methods using a mutable struct. the compiler refuses the statement

tr.replace = newreplace;

in append_replace() but accepts all of

tr.search = matches.value_of("search").unwrap().to_string();
tr.replace = matches.value_of("replace").unwrap_or("").to_string();
tr.complement = matches.is_present("complement");
tr.delete = matches.is_present("delete");
tr.squeeze = matches.is_present("squeeze");

in get_opts()

does anybody see the reason why the one is ok and the other isn’t?


#2

just found i had to add a scope:

fn append_replace(mut tr: Translation) -> Translation {
    let mut newreplace = String::new();
    {// extra scope to guard the argument
        let mut search = tr.search.chars();
        let mut replacechars = tr.replace.chars();

        let mut kar = replacechars.next();
        let mut nextkar : Option<char> = kar;
        while search.next().is_none() {
            if nextkar.is_none() {
                kar = nextkar;
            }
            newreplace.push(kar.unwrap());
            nextkar = replacechars.next();
        }
    }
    tr.replace = newreplace;
    return tr;
}

is this a normal way to do things in rust or am i missing the point of this laguage completely :blush:


#3

Yes, right now, borrowing is based on scopes. So sometimes you need to do something like this. In this case, search is borrowed from tr, so you can’t assign to tr.replace while it’s being borrowed. As you’ve seen, the scope lets search go out of scope, which then frees you up to mutate.


#4

ok, thanks. I am still afraid my total design is off but it seems at least this bit makes sense, then.