Check out a free preview of the full Rust for TypeScript Developers course
The "Default & Display Traits" 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:
ThePrimeagen implements two built-in Rust traits. The Default trait behaves like a static method and returns a new struct instance with default values. The Display trait behaves like a toString method and allows for a custom print implementation. A TypeScript-equivalent implementation is also created in this lesson.
Transcript from the "Default & Display Traits" Lesson
[00:00:00]
>> So now let's create a rectangle. Let's make sure everything's working. So if we go to our main file, we've created a rectangle, this is fantastic. Now, there's something that happens a lot with Rust, is that there's some set of data structures that require you to implement what is called a default.
[00:00:15]
Meaning that if you want to be a part of the data structure, it needs to be able to just create your struct without knowing how it's implemented. It just needs to be able to do that. And so we're gonna help it. And plus, this is kind of annoying to write, right?
[00:00:27]
I don't wanna have to write all that out if I just want, just a rectangle to test really quickly. I don't want it to write all that out. So we're gonna implement our first foreign trait, meaning we own the type, but we're gonna implement someone else's trait. So let's go over to our rectangle file.
[00:00:51]
Awesome, okay, so we're our rectangle file, and I'm gonna go like this, impl Default for, I have copilot back on, for Rect. Of course, use your load code actions. And what this will do is it will allow me to be able to just call default and produce a default rectangle.
[00:01:11]
So if you look at this, what is Self referred to? Self is kinda like a special word that refers to its implementation type. For this one, we're not really saving anything, it's just Rect. You could technically just say Rect, but something that's cool about Self is if you have a bunch of generics or lifetimes and kinda stuff on it, you don't have to define all of that.
[00:01:30]
Self just means everything. So if we got into something pretty complicated typed, it would just do it very easy for us. So we go like this, return Rect, and I'm just gonna jump over to my main file really quickly, yank that out, and paste this back in cuz I don't wanna have to type it twice.
[00:01:47]
There we go, we've implemented default, 0, 0, width 10, height 10. Kind of cool, right? Maybe, I don't know, let's find out what it did. So once you get done doing that, go back to your main file, delete all this definition stuff. [SOUND] And go colon colon, remember colon colon accesses the namespace.
[00:02:11]
If you look at the trait definition one more time, you'll notice that there's no reference to Self. This is a static method, if you will, kind of like in TypeScript. TypeScript, you do it on the class. This is kinda like accessing the class, not the instance. So I'm saying, hey, Rect default.
[00:02:27]
This will produce me out a rectangle that was defined in that default method. And so that's what we're doing right there. Okay, cool, we now have a nice little default thing. We've just implemented really our first foreign trait. Okay, kinda cool, kinda cool, right? Let's get better and faster.
[00:02:45]
All right, so the points are in the rectangle, that was a Zoolander joke, and I just read it out loud. I'm not supposed to read out titles, but I want to be able to print out the rectangle now, but I don't wanna debug print it out, right? I don't wanna have that big pretty print, I want to be able to print it like this.
[00:03:03]
Just print it like I'm printing a number. Well, we can do that. We can do that via the display trait. Again, another thing that is just kind of Rust. We're now starting to integrate with the standard library. I want to be able to use the standard stuff to be able to interact.
[00:03:21]
So we're gonna go over here, we're gonna go to our rectangle, and let's implement another trait. So I'm gonna do this, impl Display. If you have your LSP working, you want to use standard format display. Don't use standard path display, they're different. One's an interface, the other one's a struct.
[00:03:40]
So there we go, impl Display for Rect. Now, this one's a bit weird. Look at the size that method it just looks disgusting. It takes in a read only reference to self. It takes in f, which is a mutable reference to a Formatter, and it returns out a Result, which is an error.
[00:04:01]
That's a lot of stuff. So hopefully, you have your code actions working, cuz if you don't, this would be very hard to type. I see a lot of typing going on, which makes me think you don't have your code action setup. Are you using sublime?
>> I am.
[00:04:13]
>> Okay, I know you are, I saw that. All right, look at, just doing editor shaming, I'm so sorry. All right, so now that we have that, I'm gonna go like this, I'm going to say return. I mean, lot of times people don't use return. This is one of those times where I can kinda see why implicit returns feel good, but I just refuse it.
[00:04:32]
All right, I'm gonna go write. write is a lot like print, except for it takes in a formatter as opposed to just dumping it out on the standard in or the standard out. So I'm gonna go write, here's my formatter, and then I'm gonna go, okay, I want to go Rectangle.
[00:04:48]
And you can just do however you want to display your rectangle. Me personally, I'm gonna do this. I'm gonna do the x, y right there, and then I want the height by width, like that. Yeah, that feels good, I like that. For me, that's how I'd want my rectangle to be displayed.
[00:05:04]
That's how I want my cucumbers pickled. So I'm gonna go self.x, self.y, self.width, self.height, and then maybe format a little bit. I forgot a self in there, there we go. And so just like print-ln, it's using the same things, but now I've implemented for Rect. And so now my rectangle, I should be able to just print it out with two little squirlies.
[00:05:33]
I call them squirlies, I don't know what you guys call them. I saw you loud [INAUDIBLE]. We've [LAUGH] hurt my feelings over here.
>> No, I do too.
>> It's the best way to refer to the mess. If you didn't get it displayed, you can always just derive debug and pretty print it out.
[00:05:48]
But I just want to show you that you can start doing a lot of interacting with the standard library from Rust by implementing traits on your structs. So let's go back to main, and I can just do this now. Now, I can jump here, and cargo run, and look at that, rectangle at origin 10 by 10.
[00:06:12]
I made that statement, that's my statement. And so it's pretty cool, right? Which also gave us another method, because we implemented display underneath the hood, it now also gives us to_str. It's pretty cool, we're gonna learn how that happened here very, very soon, but that's pretty cool. That's super duper.
[00:06:32]
We can now stringify our rectangle. If you have a reference to the website, by the way, you can just cut and paste it. If you can't keep up or you get a little out of sync, you can always grab it from this course website. All right, so can we do this in TypeScript?
[00:06:47]
So this is the one thing I said I was gonna do in TypeScript just to show you it's possible. So I'm gonna go like this, I'm gonna jump in here. Even though I didn't move all the files around and do all the right enterprise JavaScript going on here, I'm gonna go like this, toString return.
[00:07:04]
I want to just yank that one and paste this one in here and return this. And so you can imagine, let's see, how do we do this here? We wanna go, yeah, that, yeah. And is it $1? It's $1, this.x, this.y, this.width, and this.height. So in JavaScript, I can effectively accomplish the same thing by doing that.
[00:07:33]
If I go console.log, new Rectangle 0, 0, 10, 10. Yeah, yeah, I do that and I go npx, and I run it. You'll notice that I'll get the same result. So that's kinda something that's kinda cool about JavaScript. It does allow you to hook into some level of them in a pretty standard way.
[00:07:59]
So you just have to implement the toString method.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops