3 ms·
Underscore is not exactly "throw away" but rather it is exactly "don't bind to variable". The difference becomes evident with the statement: let _ = x; Th
by kzrdude 7y ago
Underscore is not exactly "throw away" but rather it is exactly "don't bind to variable". The difference becomes evident with the statement:
let _ = x;
This is a no-op and the value remains owned by the variable x, and is not thrown away.
- nightcracker 7y agoUnderscore can also be the equivalent of a wildcard in pattern matching.
- saghm 7y agoI think that's the same thing as in let bindings; just like you can bind to a name in the wild card case, you can also choose not to bind to it. The main difference is that not binding in the wild card case is more common than in `let` bindings.
- fasterthanlime 7y agoI debated which terminology to use and thought "throwing away" was more intuitive, especially if you've never heard of "binding" before. It has its limits though - in your example I'd say you're throwing away the result of evaluating "x", just as if you did: x;
- kzrdude 7y agoI don't agree, because we can try the two following programs, and one of them does not compile. It compiles with underscore. 1: let x = String::new(); let _ = x; println!("{}", x); 2: let x = String::new(); x; println!("{}", x); // ERROR: Use of moved value x. And this is why I said that let _ = x; is a no-op. :)
- Tehnix 7y agoI think no-op is a bit misleading, and throwing away is more precise, since Rust has strict evaluation. let _ = timeConsumingFunction(); Still needs to spend time performing timeConsumingFunction(). It might not move, but it still did the work and produced a result, you are just not using it (and hence not need to move it). If you you had lazy evaluation I would agree with your argument for the no-op terminology.
- kzrdude 7y agoThat statement is different, the rhs is not a variable's name, so I agree with you, all of that is not a no-op.
- fasterthanlime 7y agoHuh, TIL! Had no idea `x;` actually moved `x`.
- AnimalMuppet 7y agoBut where is it moved to? Who owns it now? Or is it just lost?
- kzrdude 7y agoyes, it is dropped
- runarberg 7y agoAhh, I remember a while back reading a blog where the author talked about `std::mem::drop` being their favorite standard library function because they used this effect. It is literately defined as: pub fn drop<T>(_x: T) { } https://doc.rust-lang.org/std/mem/fn.drop.html https://doc.rust-lang.org/std/mem/fn.drop.html
- kzrdude 7y agoRight, so drop is useless :) We can drop things fine without it. Since of course it's scope/ownership based and not something that's explicitly called.
- AnimalMuppet 7y agoWell, drop(x); is a lot clearer than x;
- e_proxus 7y agoSo is drop like free, or is it something else?
- cyphar 7y ago
- aallen90 7y agoIn C#, _ is called a "discard" variable. I found that to be an apt term to grasp the concept quickly.
- watmough 7y agoI did wonder about this, due to consumption of ... values / refs (terminology?) ... in Rust. Thanks for adding this important detail.
- monocasa 7y agoI guess I always viewed that as dropping a reference which is a noop, but still dropping.
- da-x 7y agoThere's a difference between let _ = <expr>; and: let _x = <expr>; The first one drops ownership over the variable right after `let`, and the second drops in the end of the scope where the `let` is contained. It was mentioned in an open Rust github issue, but I can't seem to find it.