Transcript from the "Enums in TypeScript vs Rust" Lesson
>> So enums, my goodness, everyone here hates enums, right? Everyone here's a good TypeScript developer. We all say it together, I hate enums, fantastic. Everyone said it, you couldn't hear it out there on frontendmasters.com. So even Matt Pocock, the TypeScript wizard himself, says they're considered harmful. So there you go.
[00:00:17] So why are we learning enums? Well, Rust enums are just not like TypeScript enums. They have the same word, but they're just nothing the same. I would argue that they're the greatest thing to ever exist. They actually, if Go had it, Go might be the best language ever.
[00:00:31] Just because this is the one thing that makes me just insane about Go, is that you'll always do these interface lists. And you're trying to operate over, you just want the type and then you have to do all this type checking and runtime and it just feels awful.
[00:00:45] Whereas with Rust, the types and the heterogeneous style of it works fantastic with enums. You'll see really soon here. Well, I'm gonna probably just due to time, I'm gonna walk through and type it, try to follow along as we go. But we're gonna create an enum color with red, blue, green, in Typescript, and then you can start now.
[00:01:03] And then we're gonna create a singular method, printColor, which is gonna print out red for red, green for green, blue for blue. Which means you can also erase all the previous stuff we've done. So I'll do it while you guys do it. So enum Color, Red, Green, my goodness, Green, and Blue, all right, that's the colors.
[00:01:34] Then we're gonna go, fn printColor, it's gonna take in a color. Wrong fn, function, there we go. And now, we're gonna just simply do, I'll do a switch statement. And I'm gonna go case Color.Green, console, my goodness, console.log green. I forgot you have to add breaks. I always forget you have to add breaks in this language?
[00:02:04] There we go, and break. I always find that every time I use a switch statement, I feel like I've made a mistake. All right, and if I'm not mistaken, I think this was the order I had it in to make it perfect, there we go. I'm gonna say it's right here, I'm gonna definitely say it's right there.
[00:02:25] Okay, I want it to be the same as the code I put on the other screen, it's a challenge of mine. So I can go down here and I call, printColor and I can pass in, say, Color.Red, and it should just print out red for me. So if I were to go over here, run TypeScript, if I've done it correctly, red.
[00:02:41] Wow, I'm a TypeScript developer. Look at that, we've done it. How fantastic is that, right? Are you guys getting excited? I hope everybody's just so pumped up about enums, cuz it's just so great. All right, if we go here, red, green, blue, dang it. Okay, green was second.
[00:02:59] Okay, so I didn't quite nail the example code, but you get the idea. Pretty straightforward, right? I think everyone in here probably doesn't struggle with that. So let's do the exact same thing in Rust. The enum syntax is identical. So right now, you could open up Rust and start writing an enum.
[00:03:14] You should do that. And then we're gonna create a function called print_color, which is gonna do the exact same thing. But instead of using a switch statement, we're gonna use a match statement, because there is no switch statement in Rust, they have a match statement. So I'll give you a small momentary head start.
[00:03:29] Really, it's good for you to start typing, do it, it'll make you learn. All right, I'm gonna start programming it now. I just wanted to give you a moment so that way, you can kind of experience it. If you delete your main function, it'll get really angry about it.
[00:03:42] All right, so I'm gonna go, enum Color. In fact, it's so same, I'm just gonna jump up here, grab that one and just paste in. Boom, look at that, it's the exact same code, it's identical. And so now, let's go function print_color, cuz remember, they love their snake cases around here.
[00:03:59] We're gonna have a color: Color. Pretty much identical at this point, right? And I'm gonna do a match statement and pass in color. Now, if you have your LSP foo ready and you're feeling pretty froggy with it, you can call code actions and, boom, it'll fill it in for you.
[00:04:16] The Rust Analyzer is fantastic at that. Notice, it does a bunch of todos? We talked about todos, that's pretty cool. So there we go. So red, I'm gonna println!("red"). And let's go right here, and now let's do a green, no. There we go, exact same thing, right? I mean, this is truly the exact same code, maybe a little bit more condensed just because switch statements and match statements, they're not quite the same thing.
[00:04:51] I wouldn't fault that inside of TypeScript. I'm gonna call print_color with Color.Green, fantastic. Color::Green, sorry, when you're using an enum, you're got to use colon, colon, that's how you access it. So there we go. I'm parsing in green, it should print out green. So if I jump over here and go, cargo run, no, cargo road.
[00:05:15] So there we go, green, that's a good joke. Trust me, it's a great joke. Look at that, exact same code, I typed it all out. First try, all right, awesome. So right now, you're probably thinking, enums aren't that cool, right? That's not that cool, and you're not giving me anything right now.
[00:05:33] Kind of boring, and you're absolutely right. Let's try something. Let's go to our TypeScript file, and I want you to add the color yellow and tell me what happens. Well, I'll just tell you what happens since I'm already over here. I'm gonna add yellow, what happens? Nothing, right?
[00:05:52] Everything's fine, your program is great. What about yellow down here? What's our beautiful program gonna print out? Nothing, man, your program didn't even tell you that the world's changed, right, that sucks. Let's go over to Rust and go, Yellow. What happened here? You can't compile your program, you haven't considered all cases inside of your match statement.
[00:06:19] All right, so that's a good thing, right? That is something that just kind of increases a little bit, our developer awareness of what's happening within our program. So I can go down to the match, I can fill in that last one, yank that, and paste that, and boom, yellow.
[00:06:35] And now, when we go down here and we pass in yellow, well, guess what? Yellow, look how successful that is. That was really nice, right? That allowed us to be able to handle a case in which has changed. Our world has changed, Rust does not let you proceed until you fix the error.
[00:06:54] Okay, so that's a bonus, I'd say. That's at least pretty good. Here's the complete code, nothing changes over here. Boom, let's upgrade Rust, sorry, I jumped ahead a little bit. So you probably still think enum suck, honestly, you're probably right. If that's all that enums were, you're absolutely right.
[00:07:09] They'd still kinda suck, right, and why would you use them? There's no real value, but we're gonna start taking them to the next level. And you're also probably thinking, you know that match statement, that's really what did the work. Not the enum, the match statement did it. So enums still suck.
[00:07:22] Okay, okay, hold on, let me show you something. So let's create a couple methods. Let's do, is_green and is_green_parts. If you pass in green, it will turn true for is_green. If you pass in blue or yellow, it will turn true for is_green_parts. So I'm using the subtractive system of coloring.
[00:07:43] This is not the additive one, this is not CSS, okay? So I'm gonna just do this only in Rust. So we're gonna go up here above our print_color. Now, remember, on structs, how we can impl for a struct? Well, guess what? You can impl for an enum as well.
[00:08:01] Fantastic, okay, so let's go function is_green, and it's gonna take it a reference to myself, and I'm gonna return out a boolean. Remember, I talked about this. &self just means that when you're calling this, it's a read-only function. I only need to read data and that is it.
[00:08:19] I don't actually do a lot there. And so now, we can have a pretty straightforward situation. I can go like this, if let Color::Green=self, remember, we're just pattern matching. If this is true, well, then we can return true, else we can return false. Look at that, that's pretty nice.
[00:08:41] We pattern matched our way into this. So we can do this again. We can go, function is_green_parts, taking a read-only reference to self, cuz again, we don't need to mutate anything. We just simply need to look at its data, and we want to return out a boolean. So hopefully, everyone's kinda keeping up, typing along.
[00:09:01] So let's do something a little bit different here. Let's do a match statement with self. Again, if you have your code action set up on VSCode, I think if you right-click it, there's a Code Actions button and you should be able to do the exact same thing. I don't know the button you press, but it's similar.
[00:09:16] So for red, let's return false. For green, I'm just gonna do this for all those really quickly. For green, we return false. For blue, let's return true. And for yellow, let's return true. There we go, our is_green_parts now works. is_green_works, and there are methods that are hanging off an enum, which means we can probably do something pretty fantastic coming up here.
[00:09:42] I'm gonna give you one moment to kinda catch up. I know, you're all impressed with my Vim skills, I get it. I am gonna make that joke 17 more times, because you get to, because it's just part of life. And you know what's a really cool thing, is that when you learn cool technology like Vim or Rust, you gotta tell people you use it.
[00:10:02] So you gotta say, I program in Rust, by the way. And so that's called a by the way point. And the more by the way points you have as a developer, the cooler you are. So Rust, Arch Linux, Vim, Dvorak. I use Dvorak and I use Vim and I program in Rust.
[00:10:17] I don't use Arch Linux, I have kids, I don't have time to customize Linux. I'm part of a group known as Father's Against Arch Linux, it's just what it is, okay? And so now we can come down here and I can do something like this. I can create Color::Green, let's just assign that to foo.
[00:10:34] I know I always use foo, some people say don't use foo. Foo is just a placeholder for me. It's a meaningless variable, and I can go foo.is_green. Look at that, we have is_green and is_green_parts on the enum itself, that's pretty cool. That means we can do things. That's definitely at least a plus one, right?
[00:10:52] Can we agree that's a plus one? It makes it so that you have methods dangling off. Now, in TypeScript, you could totally do this. You would just have a module called colors, and you'd define your enum, export it. And then you define a function called is_green, export that, which just takes in a color and tells you if it is or is not green.
[00:11:11] The problem with that generally is that now you have to go through a module to know what's available, whereas this is on the enum itself. I'd say it's more ergonomic, right? It's a little bit more convenient. You don't have to go modules spelunking to find out what you can actually do.
[00:11:27] You don't have to go up to an import statement and make the import statement list everything. You can just simply check on the color.