Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


I 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;


I 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. :)


Huh, TIL! Had no idea `x;` actually moved `x`.


But where is it moved to? Who owns it now? Or is it just lost?


yes, it is dropped


Ahh, 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


Right, 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.


Well,

  drop(x);
is a lot clearer than

  x;


So is drop like free, or is it something else?


Yes, it's effectively like free -- though C++'s "auto" is probably a closer idea.

The main difference to C's free is that you simply cannot double-free a value (without using unsafe). That's because a value is only dropped when it falls out of scope -- and since it values only have one owner (and references must not outlive values) there cannot be any dangling references after it's dropped.

The documentation for std::mem::drop is explaining that dropping a value is a property of the language and scoping rules -- thus there is nothing for the function to do other than take a value and let it go out of scope.


It’s more like delete in c++ because you can implement the Drop trait for a type in order to run code when it is dropped in order to clean up resources etc.


Drop is just what runs when a value goes out of scope. Like destructors in C++.


When you put it like that, I see that it's a rather minor detail.


I 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.


That statement is different, the rhs is not a variable's name, so I agree with you, all of that is not a no-op.


In C#, _ is called a "discard" variable. I found that to be an apt term to grasp the concept quickly.


Underscore can also be the equivalent of a wildcard in pattern matching.


I 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.


There'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.


I did wonder about this, due to consumption of ... values / refs (terminology?) ... in Rust.

Thanks for adding this important detail.


I guess I always viewed that as dropping a reference which is a noop, but still dropping.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: