Check out a free preview of the full Rust for TypeScript Developers course

The "Options Exercise" Lesson is part of the full, Rust for TypeScript Developers course featured in this preview video. Here's what you'd learn in this lesson:

Students are instructed to write a function that takes in a Vec<usize> nums and a usize index and returns either the value multiplied by 5 at the index (if it exists) or the index multiplied by 5. The solution should be written in TypeScript first, followed by Rust.


Transcript from the "Options Exercise" Lesson

>> So let's get going. Let's actually go on to our little exercise to really set in the value that Rust is trying to bring to you. And so today we're gonna do a small little program. We're gonna call it practice. That's the function we're gonna do. And it's gonna take in numbers that is a vec of usize.

So a list of unsigned system architecture with numbers and an index, usize, and you're gonna return one of the following. So it's an iteration on the previous thing we just got done writing, if the value exists in the numbers, return it and multiply it by 5. If there is no value, return the index and multiply by 5.

So we're gonna take a vector, we're gonna pass in an index, then we're gonna grab that value out of the vector at that index, multiply it by 5, or multiply the index by 5. So, I will kinda help you. It says first do it in TypeScript, so let's do it in TypeScript first, because that's where we're gonna do it.

It's better to do it in TypeScript. So let's jump over here, let's go to TypeScript, and we can just update practice to be something that looks like this. It's gonna be a numbers array, right? Cuz we don't have vectors, we have that, so I'm gonna call it nums, it just feels better that way.

And we're gonna return out a number, fantastic. And then also, we need to be able to take in the index in which we're gonna be indexing at. So how do we do this in TypeScript land? Well, we'd have to be a little bit careful. We're gonna have to do something, maybe it looks something like this.

We're gonna have to go return (nums [index] ?? index)5 right, does that look about right? Seems about correct. And so, there we go, we have successfully done it in TypeScript, fantastic. We all know TypeScript, so this is very familiar and wonderful and just feel good about yourself. I don't think this is how I did it in the preview, which hurts my emotions.

So if I go down here, what did I do it as? Yeah, I did something like this. You don't wanna do that. You could also do it like this, or the way I just did it, which probably seems a little bit nicer. So there you go. We did the same thing.

So if I pass in this, I should get four times five, I should get 20 out if we were to execute this. So pretty straightforward code, nothing fantastic going on. Let's do the same thing, but in Rust. So let's take our vector knowledge, let's take our option knowledge and let's make it happen.

So jump back here, jump over to your Rust file. Instead of being an option of usize, let's have it as a Vec of usize. Instead of returning an option of usize let's just have it as usize. So there we go. And then lastly, we need to take in an index.

So make sure your index is, of course, a usize. There we go. So now we just gotta return this thing out. So what can we do? Well, we can return num.get(index). Now remember, what does get return as? Can someone say the type out loud?
>> Option?
>> Option of?

>> The thing [LAUGH] that's underlying it.
>> Yes, the type that's in the vector, option T. Option, the type in the vector, option of usize. You can see that right here, it tells you all about it. That definition looks extremely complicated, but don't worry, that's what's happening. So that means we can now unwrap it or we can use our previous stuff.

Now notice, we're combining our operations here, we're going into a vector. We're using those options, and we're doing the right things here. So now I can unwrap or index. But what's going on here? We got to do this really quickly, times 5, and we have this problem here.

So if you wrote the same code I did, which is vector dot get index, unwrap or index, what does this mean? Expected reference to usize found usize. Let's walk through this problem, what could that mean? What does get return? Let's look at it. Gosh, I can't even see my mouse.

4K, caught in 4K here. Notice what it says. It's an option of reference to what's inside. It's not the item itself, it's a reference to what's inside the vector. That means if we were to do something like this, let num = num get index off. We can't use that, we'll just call unwrap for now.

Look at what we get. We get a reference to the thing that's in the vector, not the thing that's in the vector, a reference to it. So that's very, very important. Which means unwrap or has to do what? It has to match the type that's coming out. So the or has to be the same.

So we can just go like this, reference to index. Boom, it's the same type now. We were trying to unwrap or with a different type. We have to make it the same type. Kind of a fun little experiment there. You kinda can see a little bit more about how these things work.

You gotta think in types. Thinking in types really helps you kind of have a good mental pathway when you're building a program. So a little bit different maybe than you're used to, especially if you're only doing TypeScript ever. An ampersand sign should only ever be used in IF conditions.

This is ridiculous that you're using it somewhere else. Well, technically, a Boolean expression would be a better way to say that, but you get the idea. All right, we did the Rust version. Does that all make sense? Do you feel a little bit better about that? Yes, we're trying to keep the types the same when you unwrap.

All right, so we already, yeah. So anyways, this is Rust's take on the billion dollar mistake that is known as null or undefined. Null really is the billion-dollar mistake, that's what they call it. I would argue that undefined's potentially even more than a billion-dollar mistake, undefined has been just a nightmare.

I think one of the hardest parts about undefined is if you ask any person, say, what's the difference between null and undefined, you get kind of a variety of answers. The main answer you're gonna get is null is undefined on purpose and undefined is undefined on accident or purpose sometimes, right?

Because why would you have that little question mark operator on a struct if it's on purpose? If it's on purpose, then say it's on purpose, it's null. So we don't use it consistently. It has weird meanings. It's like a holdback from Java. I don't know what happened, right, because if you don't know, Brendan Gregg, he did actually have to bring it over because of demands with Java to bring over null into JavaScript, blah, blah, blah, blah.

Who knows? It had to do something with integration. I forget the exact reason, but, anyways, here we are, we now have a completely different take on the null undefined problem. And I would argue that this just leads to easier programming. You always know when something might not be there.

And right now you're probably thinking in your head. Well, it's not that big of a deal. We generally know, just wait.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now