DEV Community

Cover image for 30 Days of Rust - Halfway

Posted on

30 Days of Rust - Halfway

Wohoo, we've made it to the halfway point 💪 For those following carefully, it hasn't quite been 15 continuous days, but in sum we've written 15 Rust blogs and learned (and suffered) a bunch. I'm not going to mark this blog with anything special. My only goal right now is to finish the Rust book by day 30. Let's goooo!

Yesterday's questions answered

  • A const function simply describes a function that is called from with in a const context. A const context exists in specific expressions, particularly those linked to array size and length declaration and as well as const, static and enum declaration. const functions are called at compile time.
  • The "use case" for integer overflow seems to be limited to primarily the crypto world. I found an article explaining how to handling for a specific type of smart contract (I didn't really read it, it's too early for smart contracts!!!). Another situation could be in a memory restrictive environment. Imagine a tiny CPU processing requests from sensors in some kind of embedded system. If one of those sensors is faulty or there is a bug in the communication protocol (the latter being unlikely) the CPU could receive a 256 instead of 255, leading to an overflow.

Today's open questions

  • What is a static?

Fun fun FUNctions

We already covered the basic syntax of functions, particularly in day 3. I'll add some summary points that I've learned to better express how functions work.

Remember, a function in Rust can return a value in Rust by ending in an expression or a return statement. The Rust book provides useful definitions for those terms:

Statements are instructions that perform some action and do not return a value.
Expressions evaluate to a resultant value

We can see now that the return keyword offers a unique behaviour for statements in Rust. This also explains why you cannot chain declaration statements in Rust, as a statement does not return a value, for example in Python:

x = y = 6
print(f"{x}, {y}")
# 6, 6
Enter fullscreen mode Exit fullscreen mode

Functions, however, are not the only instance where expressions in an inner scope can be used to return a value to an outer scope in Rust. We've already encountered this a few times:

let x = {
    let x = 2;
    x + 2
println!("x = {x}"); // 4

let y = match johnny_is_awesome {
    Ok(johnny) => true,
    Err(_) => false
println!("Is Johnny awesome? {y}");

Enter fullscreen mode Exit fullscreen mode

We could use a loop or if expression in a similar fashion. What's interesting here is that Rust is consistent to the definitions it stated above. And I'd like to shamelessly speculate that the inclusion return statement may even be a historical product from programming tradition (or to make Rust seem not too try hard hipster).

Quickly on ifs

I'm pretty certain I've been mistakenly calling if expressions if statements for the entirety of this blog 🐒 Kudos if you spotted those mistakes. As noted above it's possible for a value to be assigned from an if expression in Rust. As such (and this is also true for match expressions), each arm (aka block) of an if expression must yield a result of the same type (only if you care about your code compiling, of course). I'm guessing my confusion stems from the Python world where if is rarely used as an expression:

args = args if args else {}

if not args:
    args = {}
Enter fullscreen mode Exit fullscreen mode

Even quicker on loops

A couple of neat tricks for loops in Rust:

  • You can label a loop. This label can be used by the continue or break keywords (not specifying the label will break the innermost loop of the current scope). Note the single ' here, it's not a typo:
'outer: loop {
    'inner: loop {
        if ... {
            break 'outer;
        } else {
            break; // Breaks 'inner
Enter fullscreen mode Exit fullscreen mode
  • Range iterators have a rev method which will reverse the order of the range!

Top comments (0)