How to return an immutable reference of a mutable Vector?

Hi,

starting with Rust creates many questions. I hope I dont bother you...

I have the following construct.

   pub fn get_double_tokens(css_path : &str) -> Vec<CSSToken> {
        let css_token_list: &mut Vec<CSSToken> = &mut Vec::new();
        check_files(css_token_list, css_path);
        search_for_double_tokens(css_token_list);
        css_token_list; <- not working because wrong type
    }

    fn check_files(list: &mut Vec<CSSToken>, path: &str)  {
          ..... 
    }

The function check_files ist recursivly called and modifies the content of the css_token_list (Bei adding elements). So the list must be mutable first. But the resulting (returned) list should be inmutable, so that I can call get_double_tokens in that way

let css_token_list = get_double_tokens("path");

and get back a reference to an unmutable list (because mutable is not nessecary here)

How is this handled in Rust?

Thanks

Claus

There's not really a way to prevent the user from mutating the returned Vec<CSSToken>; they own it, so they're allowed to do whatever they want with it. If you want to prevent that, you could return a Box<[CSSToken]> by calling the into_boxed_slice() method on css_token_list, but that's not really idiomatic Rust; I'd just leave it at returning a Vec:

pub fn get_double_tokens(css_path: &str) -> Vec<CSSToken> {
    let css_token_list = Vec::new();
    check_files(&mut css_token_list, css_path);
    search_for_double_tokens(&mut css_token_list);
    css_token_list
}
1 Like

It also doesn't work because you can go from a boxed slice into a Vec with From/Into.

If you really care the Vec isn't modified, you could use the new type pattern/idiom.

Also Rust's references are not just pointers, meaning this: &mut Vec::new() has no reason (I can think of) to exist.

This isn't a complete solution doesn't because you could overwrote the whole new type, but it does make it significantly harder to mutate the vec.

What to you mean by:

reassign something else?

Yes, but thinking about it some more I guess that isn't the type of mutation they want to block. So a newtype is a good solution to this.