I’ve been using Rust for a few months now, writing rather more of it than I expected – though quite a lot of that has been thrown away as I’ve learnt improved what I’m writing and taken some more complex tasks on beyond what I’d originally intended. I still love it, and thought that today might be a good day to talk about some of the important keywords that come up again and again in Rust, and provide my personal summary of what they do, why you need to think about how you use them, and anything else that’s useful, particularly for people who are new to Rust, or coming from another language (such as Java – see my previous article on the subject, 5 Rust reflections (from Java)). Without further ado, let’s get going. A good place for further information is always the official Rust documatation – you’ll probably want to start with the std library.
- const – you get to declare constants with “const”, and you should. This isn’t rocket science, but do declare with const, and if you’re going to use constants across different modules, then do the right thing and create a lib.rs file (the Rust default) into which you can put all of these, with a nicely name module. I’ve had clashes of const variable names (and values!) across different files in different modules, simply because I was too lazy to do anything other than cut and paste across files, when I could have save myself lots of work by simply creating a shared module.
- let – you don’t always need to declare a variable with a let statement, but your code will be clearer when you do. What’s more, always add the type if you can. Rust will do its very best to guess what it should be, but may not always be able to do so at runtime (in which case Cargo, the compiler, will tell you), or may even not necessarily do what you expect. In the latter case, it’s always simpler for Cargo to complain that the function you’re assigning from (for instance) doesn’t match the declaration than for Rust to try to help you do the wrong thing, only for you to have to spend ages debugging elsewhere.
- match – match was new to me, and I love it. It’s not dissimilar to “switch” in other languages, but is used extensively in Rust. It makes for legible code, and Cargo will have a good go at warning you if you do something foolish (such as miss out possible cases). My general rule of thumb, where I’m managing different options or doing branching, is to ask whether I can use match. If I can, I will.
- mut – when declaring a variable, if it’s going to change after its initialisation, then you need to declare it mutable. A common mistake is to declare something as mutable when it isn’t changed – but the compiler will warn you about that. If you get a warning from Cargo that a mutable variable isn’t changed when you think it is, then you may wish to check the scope of the variable, and check that you’re using the right version.
- return – I actually very rarely use return, which is for returning a value from a function, because it’s usually simpler and clearer to read if you just provide the value (or function providing the return value) at the end of the function, as the last line. Warning: you will forget to omit the semicolon at the end of this line on many occasions: if you do, the compiler won’t be happy.
- unsafe – does what it says on the tin: if you want to do things where Rust can’t guarantee memory safety, then you’re going to need to use this keyword. I have absolutely no intention of declaring any of my Rust code unsafe now or at any point in the future: one of the reasons Rust is so friendly is because it stops this sort of hackery. If you really need to do this, think again, think yet again, and then redesign. Unless you’re a seriously low-level systems programmer, avoid.
- use – when you want to use an item – struct, variable, function, etc. from another crate, then you need to declare it at the beginning of the block where you’ll be using it. Another common mistake is to do this, but fail to add the crate (preferably with minimum version number) to the Cargo.toml file.
This isn’t the most complicated article I’ve ever written, I know, but it’s the sort of article which I would have appreciated finding when I was starting to learn Rust. I plan to create similar articles on key functions and other Rust must-knows: let me know if you have any requests!