Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there Rust variable naming conventions for things like Option<T>?

Is there a convention for variable naming in cases like the following? I find myself having to have two names, one the optional and one for the unwrapped.

let user = match optional_user {
    Some(u) => {
        u
    }
    None => {
        new("guest", "guest").unwrap()
    }
};
like image 648
Bruce Avatar asked Nov 01 '14 20:11

Bruce


2 Answers

I'm unsure if there is a convention per say, but I often see (and use) maybe for Options. i.e.

let maybe_thing: Option<Thing> = ...
let thing: Thing = ...

Also, in regards to your use of u and user in this situation, it is fine to use user in both places. i.e.

let user = match maybe_user {
    Some(user) => user,
    ...

This is because the match expression will be evaluated prior to the let assignment.

However (slightly off topic) @Manishearth is correct, in this case it would be nicer to use or_else. i.e.

let user = maybe_user.or_else(|| new("guest", "guest")).unwrap();

I'd recommend becoming familiar with the rest of Option's methods too as they are excellent for reducing match boilerplate.

like image 95
mindTree Avatar answered Sep 28 '22 01:09

mindTree


If you're going to use a variable to initialize another and you don't need to use the first variable anymore, you can use the same name for both variables.

let user = /* something that returns Option<?> */;
let user = match user {
    Some(u) => {
        u
    }
    None => {
        new("guest", "guest").unwrap()
    }
};

In the initializer for the second let binding, the identifier user resolves to the first user variable, rather than the one being defined, because that one is not initialized yet. Variables defined in a let statement only enter the scope after the whole let statement. The second user variable shadows the first user variable for the rest of the block, though.

You can also use this trick to turn a mutable variable into an immutable variable:

let mut m = HashMap::new();

/* fill m */

let m = m; // freeze m

Here, the second let doesn't have the mut keyword, so m is no longer mutable. Since it's also shadowing m, you no longer have mutable access to m (though you can still add a let mut later on to make it mutable again).

like image 44
Francis Gagné Avatar answered Sep 28 '22 00:09

Francis Gagné