I've written a few articles about Rust now, including (most recently) My top 7 keywords in Rust, in which I promised a follow-up article. The keywords article talked about keywords from the std library, and in this article, I'm going to look at some functions from the Rust prelude.
When you create a file in Rust and then compile it, you can (and will often need to) import external modules, typically with the use
or extern
keywords. Rust does a good thing for you, however, which is to import a set of useful modules without you even asking. This is known as the standard prelude. As usual, the Rust documentation has good information about this.
Here are a few of my favourite functions from the standard prelude: useful ones to which I keep returning and some that expose a little about how Rust "thinks" about the world.
- clone() – There are times when you need to use a variable somewhere where Rust's rules of memory management make that difficult. Luckily, where the
std::clone::Clone
trait is implemented (which is pretty much everywhere), you can copy to a new variable. Don't do this just to get around Rust's memory management, which is there to help you, but it can be very useful when you actually need a new copy of something. - format!() – OK, officially, this is a macro rather than a function, but it's very useful. You probably know and use
println!()
, which is used to print to stdout.format!()
does pretty much the same thing for strings that you don't immediately want to output. - is_ok() – To be honest, this is just an excuse for me to talk about
std::result::Result
, which is hugely useful and allows you to create and access success (Ok
) or failure (Err
) results. Theis_ok()
function will tell you whether what you have is an Ok result (and remember that the "k" is lower case—probably my most frequent syntax error when writing Rust). In order to understand Rust properly, you need to get your head aroundResult
. It's used extensively, and you should be using it, too. - is_some() – Like Result,
std::option::Option
is something you're likely to use a lot when you're writing Rust. Given that there's no equivalent to theNull
that you use in many other languages, what can you do when you don't have a value generated to return? The answer is that you can use anOption
, which you can give aNone
value; in other cases, you can provide a value within aSome()
wrapper. Theis_some()
function checks whether there is a value—if there is, you can use theunwrap()
function to access it (see below). LikeResult
, get used to usingOption
, as you'll see it all over the place. - iter() – Many different collections can be iterated over, and the
iter()
function allows you to access all of the values very simply. You may sometimes want to use the related functionsinto_iter()
anditer_mut()
(for mutable values, unsurprisingly), butiter()
is what you'll be using the most, and you can chain all sorts of useful functions onto it. - panic!() – There are times when your program gets input or generates output that it really shouldn't. When
std::result::Result
isn't good enough, and you can't propagate errors up through your execution stack because this isn't the sort of error that should be handled, you can force your program to stop withpanic!()
(another macro, if I'm honest), and add an error message to provide more information. - unwrap() – If you've got a
std::option::Option
or astd::result::Result
, and you want to access what it contains, then you'll want to useunwrap()
, which will panic if there's a problem (orexpect()
if you want to be able to add a specific message).
This is a fairly basic article, but if it's useful for people starting to get their heads around Rust, then I'm happy. I plan to continue looking at some of the more basic language components in Rust and some basic gotchas, so keep an eye out.
This article was originally published on Alice, Eve, and Bob and is reprinted with the author's permission.
Comments are closed.