Hacker News new | past | comments | ask | show | jobs | submit login

It's not JavaScript easy, but it's not too hard once you wrap your head around Cell, RefCell, Rc, and friends.

Here's an example using GTK that does something vaguely useful, I have no idea if it's considered idiomatic, but it works as intended: https://github.com/seaneshbaugh/image_viewer/blob/master/src...

The closures themselves are trivial, it's manipulating the stuff outside the closure that's tricky (for a Rust neophyte like me).

The relevant definitions are

  let area = Rc::new(RefCell::new(DrawingArea::new()));
and

  let scale = Rc::new(Cell::new(1.0));
Rather than just define things as usual they need to be wrapped in a Cell (for value types) or RefCell (for reference types) and then wrapped in an Rc so we can keep track of reference counts at run time.

  {
      let scale = scale.clone();

      let area = area.clone();

      window.connect_key_release_event(move |_, key_event| {
          let mut s = scale.get();

          let key = key_event.get_keyval() as i32;

          if key == gdk_sys::GDK_KEY_plus {
              s += 0.1;
          } else {
              if key == gdk_sys::GDK_KEY_minus {
                  s -= 0.1;
              }
          }

          scale.set(s);

          area.borrow().queue_draw();

          Inhibit(false)
      });
  }
Inside the new scope (which is very important) scale and area are cloned which increments their count, then inside the close scale.get() is used to get a copy of scale (which is possible since it's a float) and then after doing stuff to it based on the key that is pressed it's set using scale.set(). For area it's a bit trickier, it has to first be borrow()'ed before anything can be done with it.



A bit of bikeshedding on the code you linked:

Why are you commenting out code? If you delete it, it will still be in your git history. If you have some reason to leave it in, document why and wrap it with a `if false {}` or `if debug {}` instead. That way autoformatters will not destroy your code and the compiler makes sure your code keeps compiling.

Leaving a line empty between statements helps structuring code. Putting an empty line after each statement makes the code as unstructured as without.


My personal reason for commenting out code for a few revisions, instead of deleting right away, is to keep a reminder of the work in progress. When I'm satisfied that the old code's really done for, I delete it and leave it to the history.

Until then, it's easier to review the commented-out bits than to go back through version history. (And plenty easy to delete it when it's ready to be deleted!)


Your VCS should really make it quite easy to go back through version history. If it's not doing that, that's a separate problem.

Maybe it's just me, but I find it an eyesore to have large blobs of commented out code laying around even for a short period (not to mention the odds of me remembering to delete them are close to nil).


How do you remember which commit to diff against? How do you easily pick out the relevant parts of that diff once many changes have occurred - months or even years later?


> How do you remember which commit to diff against?

Ideally your commit message would indicate this. If you're always consistent in the language you use to describe similar changes, you can just search through your git log to find it.

> How do you easily pick out the relevant parts of that diff once many changes have occurred - months or even years later?

You can use `git show` to just look at that one commit where you deleted the code


Seems fairly comparable to the way it's done in C++11 lambdas.


C++ lambdas and Rust closures are very similar as far as I know, the only major difference being that they use explicit capture lists and we don't.


On the other hand, Rust closures do compute the capture list, and then let the type system reason about the safety of those captures, which C++ lambdas (or blocks with the clang blocks extension) don't.


Ah okay, so rust will only ever capture the minimal set of what's necessarily used in the lambda? Different from using [&] or similar in C++ where you capture everything.


Yeah, in C++ you can sort of get away without explicit capture of all variables too by doing [=] or [&]. Though I suppose it's still explicit in a way, just saves the need to list everything.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: