Diving into Rust: My Journey So Far and a Few Hiccups

Hey everyone,

So, I just wanted to share a bit about my journey with Rust so far. I’m fairly new to the language, having started about three months ago. At first, I was kinda intimidated by all the ownership and borrowing rules. Like, why can’t I just pass a variable around without thinking too much about it? :thinking:

But once I got past that initial learning curve, I started really enjoying it! The safety guarantees are pretty amazing. I’m currently working on a small command-line tool to help me manage my personal projects. It’s basically just a glorified to-do list, but it’s been super fun to build. I love how Rust forces you to think ahead in your code, like ensuring you don’t run into race conditions.

I ran into some hiccups with the borrow checker at first. There was this one time where I spent a whole afternoon trying to figure out why my code kept throwing errors. I eventually realized it was because I was trying to return a reference to a variable that was going out of scope. Classic newbie mistake! :sweat_smile: But hey, that’s part of the learning process, right?

I’ve also found the community to be really helpful. I’ve been lurking on some forums and it’s great to see how supportive everyone is, especially when you ask about those beginner struggles.

Anyway, just wanted to share my experience so far! If anyone else is starting out or has tips for handling Rust’s quirks, I’d love to hear them. Cheers!

Happy coding!

My traditional list is suggestions is:

  • Don't forget to actually read the error messages! I know it sounds dumb, but especially coming from other languages it's easy to get in the habit of skipping over the details since they rarely are helpful there. Rust tries hard to give good advice in errors if it can, though of course it doesn't always know what you're trying to do, so make sure it makes sense for what you're attempting.
  • Similarly, don't try to blindly "push past" repeated compiler errors, particularly lifetime/mutability issues: if a borrow is not obvious and easy it's probably not worth the complexity, and you are better off just copying data, or ref counting (Rc or Arc types) - in particular there are several known patterns that should be accepted but currently aren't for internal reasons (you might hear about "Polonius" which is the long running attempt to fix this)
  • As a special case, you almost never want types with a lifetime parameter unless it's really obvious what it's for: a lock target or a parser source buffer for example. Otherwise you're just asking for pain, since you're probably accidentally trying to create a self-referencing structure, which is not supported outside of some very carefully designed crates like yoke or ouroborus
  • Speaking of which, don't hesitate to pull in public crates. They are generally easier to manage and higher quality than in other languages in my experience, and definitely can do a lot more for you and are harder to misuse.
    • In particular, if you feel the language is "missing something" or is being annoyingly verbose, there's probably a crate for that. Error handling, enum conversion, various async bits, test runners, and many more.
    • I like the lib.rs experience here, just type "lib.rs?something" into your browser, or just browse their curated categories, but that's subjective
  • But didn't forget about the standard library! Even if it tries to be pretty conservative with what it adds, it's still very powerful, with a lot of tricks to make dealing with complex types easier than you might expect. std.rs is a quick shortcut to the official reference here that, in particular, will let you search for methods by signature
  • Previously, I had a bit more warning about some async stuff, but that's recently gotten a lot smoother. There's still some issues, but they get a bit too in the weeds to be reasonable to try and flag ahead of time, other than:
    • every problem can be solved with either more boxes or less boxes
    • async trait methods are still a bit rough, maybe stick with the async_traits crate if you have trouble

I ended by creating a cheat sheet for myself. I do not read books, too boring, but I keep the cheat sheet handy.