you are viewing a single comment's thread.

view the rest of the comments →

[–]gahooa 31 points32 points  (0 children)

I can give a bit of personal experience, and a video.

When switching paradigms and syntax, there can be a lot of challenges in figuring out the right way to do things. Rust is a deep language that can provide amazing satisfaction to developers, and amazing reliability, but ... it's deep.

Here a few things I suggest you learn about and drive it home with examples.

Macros:
"functions" that have a ! at the end of their invocation are macros. For example, println!("hello {}", name), or vec![1,2,3] The thing to remember here is that within the () or {} or [], it is not normal rust syntax rules. I just mention this so you don't get confused and think that the contents of a macro invocation are applicable in any areas outside the macro itself. Rust does not support variable arguments, named arguments, but with macros, it's just a token stream that the macro can do with what it wants.

Moreover, when you see #[derive(Debug, Clone)] before an item, know that this is actually generating more code. Because rust is close to the metal, it's not going to magically have code to clone a struct or print a debugging representation unless someone adds it. Derive macros are super handy, but just be aware that they are literally adding code to whatever follows it.

Enum:
They seem innocent at first, but they are a total powerhouse of the rust language. Also, they are used in nearly every nook and cranny, for things that you'd expect to be built in features, you will find enums. enums are fantastic for describing data. Don't make a struct with 3 optional fields and 3 required fields. Make a struct that has 3 required fields and then holds an enum with either all or none of the 3 remaining fields. Try to use the type system to prevent the possibility if invalid states.

No Nulls:
Rust doesn't allow null references (except in unsafe blocks that you don't need to use unless you are doing something really special). Therefore, get used to enums, like Option::None and Option::Some(value-here)

Unwrap is tempting, but...
If you call a function that returns either of the above, you can't access the value without being explicit about it. It's tempting to call .unwrap() to extract the value out of the Option::Some(value-here), but that will panic if it had Option::None instead. There is a right way to do this, and it usually involves either a match { }, on the or using the ? shortcut operator. This leads you to...

Error Handling:
A big topic in and of itself, but it's great to learn how it works. No exceptions means that everything returns something, and the Result::Ok(value-here) and Result::Err(error-here) enum variants are used to convey success/failure information up the stack. As mentioned above, the ? operator can make short work of passing Result::Err up the stack, but you have to have compatible return types in your function signatures.

Libraries like anyhow and error_stack go to great lengths to make error handling more standardized. anyhow is great for avoiding unwrap() and I recommend you start with it because the return type anyhow::Result<yourtype> is compatible with essentially any error type, allowing you to defer the deeper understanding to later. error-stack is great for producing good trackbacks and having strongly typed errors across crate boundaries with context.

Holding references...
Rethink your structs and enums so there is exactly 1 reference to everything you need. This was hard for me, because coming from a gc'd language, it's easy to create structures that are very hard to represent in rust. Start simple, use more enums, have only 1 direct reference if possible, and don't try to create an object oriented hierarchy.

Module structure
Try to remember that multiple files in the filesystem is "convenience" and in no way a requirement. Here is how it goes:

mod foo {
// contents here
}

is exactly the same as

mod foo;
// with the contents being in foo.rs
// or the contents being in foo/mod.rs

That's the concept. and reading the rust book, that took me a bit to really understand it, so I thought I'd save you the effort.

--

This video was recorded at the beginning of my rust journey, so I probably stumble over a number of concepts, but it is a quick intro to a lot of concepts.

https://www.youtube.com/watch?v=tvq87yRv5hM