# Let binding

### Always separately bind RAII guards. [FIXME: needs RFC]

Prefer

fn main() { fn use_mutex(m: sync::mutex::Mutex<i32>) { let guard = m.lock(); do_work(guard); drop(guard); // unlock the lock // do other work } }

    fn use_mutex(m: sync::mutex::Mutex<i32>) {
        let guard = m.lock();
        do_work(guard);
        drop(guard); // unlock the lock
        // do other work
    }

over

fn main() { fn use_mutex(m: sync::mutex::Mutex<i32>) { do_work(m.lock()); // do other work } }

    fn use_mutex(m: sync::mutex::Mutex<i32>) {
        do_work(m.lock());
        // do other work
    }

As explained in the RAII guide, RAII guards are values that represent ownership of some resource and whose destructor releases the resource. Because the lifetime of guards are significant, they should always be explicitly `let`-bound to make the lifetime clear. Consider using an explicit `drop` to release the resource early.

### Prefer conditional expressions to deferred initialization. [FIXME: needs RFC]

Prefer

fn main() { let foo = match bar { Baz => 0, Quux => 1 }; }

    let foo = match bar {
        Baz => 0,
        Quux => 1
    };

over

fn main() { let foo; match bar { Baz => { foo = 0; } Quux => { foo = 1; } } }

    let foo;
    match bar {
        Baz => {
            foo = 0;
        }
        Quux => {
            foo = 1;
        }
    }

unless the conditions for initialization are too complex to fit into a simple conditional expression.

### Use type annotations for clarification; prefer explicit generics when inference fails. [FIXME: needs RFC]

Prefer

fn main() { let v = s.iter().map(|x| x * 2) .collect::<Vec<_>>(); }

    let v = s.iter().map(|x| x * 2)
                    .collect::<Vec<_>>();

over

fn main() { let v: Vec<_> = s.iter().map(|x| x * 2) .collect(); }

    let v: Vec<_> = s.iter().map(|x| x * 2)
                            .collect();

When the type of a value might be unclear to the reader of the code, consider explicitly annotating it in a `let`.

On the other hand, when the type is unclear to the compiler, prefer to specify the type by explicit generics instantiation, which is usually more clear.

### Shadowing [FIXME]

> [FIXME] Repeatedly shadowing a binding is somewhat common in Rust code. We need to articulate a guideline on when it is appropriate/useful and when not.

### Prefer immutable bindings. [FIXME: needs RFC]

Use `mut` bindings to signal the span during which a value is mutated:

fn main() { let mut v = Vec::new(); // push things onto v let v = v; // use v immutably henceforth }

    let mut v = Vec::new();
    // push things onto v
    let v = v;
    // use v immutably henceforth

### Prefer to bind all `struct` or tuple fields. [FIXME: needs RFC]

When consuming a `struct` or tuple via a `let`, bind all of the fields rather than using `..` to elide the ones you don't need. The benefit is that when fields are added, the compiler will pinpoint all of the places where that type of value was consumed, which will often need to be adjusted to take the new field properly into account.