Dud this content is soo much better than: "Will Rust substitute X" or "Is Rust dead in 2033". Really liked the examples, simple but to the point, helps the users of other languages to quickstart their Rust journey. Great job!
Great video man! I'd maybe recommend adding the word "Rust" in the title somewhere to attract more viewers. Maybe even "Class Based OOP vs Rust Traits". Cool comparison nonetheless!
This is exactly what I want. I'm using OOP principles too many years and I'm thinking this way when I code. Rust hasn't objects and this is confusing my mind. But now everything is more clear for me. Thanks for this bro.
I feel like this video should have also brought up interfaces in Java, since they are very close to what traits allow us to do in Rust. The way you presented it suggests that Java lacks this way of such an abstraction.
1:00 a thing to note, the “constructor” function need not be called new. A reason this can be useful is that rust doesn’t allow overloading, so if you want to create a struct from another struct, you may want to do struct A {} struct B {} impl A { fn from_B(foo: B) -> A { // constructor stuff } }
I'm a youtuber too and I'm constantly in awe of how he does it. You'd have to perfectly cut things out again and again in the correct order! I just type in the code and basically say boom! with a cut or something ahhaahhaha
Would really love to see you do a basic video on fyrox or bevy. I think rust has massive potential as a game dev language but it has very limited tutorials or educational content
Awesome video on quite complicated topic. Rust is not so difficult for newcomers in terms of syntax and stuff, but these paradigms are not widely used in popular languages. Your explanation on them is a gem! Please create more videos on these aspects of programming Rust.
If I am not mistaken, with dyn, you have a smaller artifact but it will cost you more memory to use dyn at runtime. And when we use trait bounds, we get the opposite result.
Yes, because generic trait bounds result in monomorphization, meaning that specialized versions of the defined functions are generated for each concrete type used. Therefore you end up with effectively more code, but this code doesn't need to dynamically check the type being used.
Wow I like this kind of comparative learning very much and is very easy to gain all the information and adapt from a language i already know Insted of learning the whole thing again
dude yesterday I realized that PHP has traits too and is nice the way they implemented it also "apparently" PHP is a strongly and static typed language
I don't understand your sentence at 3:53: "imagine we had a library which exposed the Animal trait, so that other developers can implement custom Animals. In that scenario we would had no way of knowing what concrete types implement our Animal trait. Because of this we would want to use trait objects". In most scenarios it is perfectly possible to use generics because all libraries are compiled together. Most of the time it is much more simple to use generics and trait objects should only be used as a last resort. Your vector example is a good use case for that. Another use case would be to use trait objects for returning a dynamic trait from a function. But then again you could use Enums for that. A third use case would be using the Error and Any traits from the standard library.
These videos are just fantastic. You clearly have in-depth knowledge of Rust and computer science. The topic of this video is probably the one that I have struggled most with regarding Rust. Where do we draw the line between what we should do and what we can do? I was going down the path of implementing encapsulation using enums and match statements, the issue with this approach is that now I have code representing each struct type spread across many places. Your recommended approaches in this video avoid that, but we are ending up with pure functions instead of struct based methods. It is still not clear what the recommended approach is. Some side notes: * I keep running into situations where it looks like traits would be a lot easier to use if they included struct properties. I would allow me to create default implementations without having to provide methods for manipulating the properties. * I have a small suggestion regarding your videos. If you paused for just one more second after you have completed an example before switching away from the code, then it would be easier to stop the video and read through the code. I often find that I have to go back and find the exact frame where everything is done so that I can read through the code, this would just make it easier and not add a lot of time to the video.
While the compiler where expand the function for each concrete type you use to call this function, this doesn't mean you have to know ALL concrete types you might use in the future. If your Animal trait is available via a library I still can implement my own type that implements Animal and call the function and the compiler (at this moment) will still generate the correct function in my binary (not in the library). This approach is way more efficient than actually using dynamic dispatching, the only down side is that it produces a bigger binary file.
Traits are like Java interfaces. When you try to create inheritance with traits, is unavoidable to duplicate code, like "impl Animal for Human" and "impl Animal for Dog". With inheritance, you can inherit not only functions, but attributes.
The classy OOP has an advantage (I know little about Rust. Correct me If I'm wrong). That is, we know what methods are available for this class. But in the struct based Rust, we don't know what method it offers. If the method is a common one, then we have to guess if that is already available or not. Or we have to implement it ourselves, e.g. to_string() method.
If performance is the issue use generics instead of dynamic as vtable lookups cost at runtime where as generics just compile down to a jmp call. Nesting structs is absolutely fine and is usually faster in rust than other OOP languages as more sized objects can be determined at compile time
As always this is great! But can you also post the code as it would be nice to be able to go through it on the side, regardless of how contrived the examples are?
Generics and polymorphism serve different purposes. They seem similar on the surface, but they are not substitutes for one another. Think about it. Java already has polymorphism, why would it introduce generics? Generics is for a particular algorithm that applies to different types. Polymorphism is more about a class of behavior where the algo impls can be different.
well, that was rapid fire but basically pretty good but it didn't bring up Java interface and how it has a similarity to traits and of course Java also does generics IOW, this subject would need more time/detail to do a more thorough comparison of Java class to Rust trait but for something so brief it was pretty good
The first programming tutorials I ever followed were by @thenewboston (Bucky Roberts). I have never since been able to find tutorials that were as clear and to-the-point. Until now! Thanks for the work you put into these, it is greatly appreciated. 😄
📝 Get your *FREE Rust cheat sheet* :
www.letsgetrusty.com/cheatsheet
Dud this content is soo much better than: "Will Rust substitute X" or "Is Rust dead in 2033". Really liked the examples, simple but to the point, helps the users of other languages to quickstart their Rust journey. Great job!
Who the hell posts that clickbait shit?
@Pieter Talens welp, good I didn't follow this channel. But stuff like this is why people complain about Rust community.
this guy has a video "Is Rust dying in 2022?"...
as a java dev. whos getting into rust i love this
thx a lot
Why?
Great video man! I'd maybe recommend adding the word "Rust" in the title somewhere to attract more viewers. Maybe even "Class Based OOP vs Rust Traits". Cool comparison nonetheless!
I searched rust oop and it led me to this video, maybe TH-cam's algorithm takes channel name also into account.
This is exactly what I want. I'm using OOP principles too many years and I'm thinking this way when I code. Rust hasn't objects and this is confusing my mind. But now everything is more clear for me. Thanks for this bro.
I feel like this video should have also brought up interfaces in Java, since they are very close to what traits allow us to do in Rust. The way you presented it suggests that Java lacks this way of such an abstraction.
That's what I have been thinking every time he was discussing traits during this series: they are basically interfaces.
1:00 a thing to note, the “constructor” function need not be called new. A reason this can be useful is that rust doesn’t allow overloading, so if you want to create a struct from another struct, you may want to do
struct A {}
struct B {}
impl A {
fn from_B(foo: B) -> A {
// constructor stuff
}
}
Ah yes, Fireship's CTRL+Z method for explaining code. I love it, and you really made good use of it. Great video :D
I'm a youtuber too and I'm constantly in awe of how he does it. You'd have to perfectly cut things out again and again in the correct order! I just type in the code and basically say boom! with a cut or something ahhaahhaha
Would really love to see you do a basic video on fyrox or bevy. I think rust has massive potential as a game dev language but it has very limited tutorials or educational content
Bevy just had a big update. They have allot of examples. I also think this tech will grow allot in the future.
Most people coming from OOP (like myself) can benefit greatly from these sort of Videos.
Awesome video on quite complicated topic. Rust is not so difficult for newcomers in terms of syntax and stuff, but these paradigms are not widely used in popular languages. Your explanation on them is a gem! Please create more videos on these aspects of programming Rust.
If I am not mistaken, with dyn, you have a smaller artifact but it will cost you more memory to use dyn at runtime. And when we use trait bounds, we get the opposite result.
Yes, because generic trait bounds result in monomorphization, meaning that specialized versions of the defined functions are generated for each concrete type used. Therefore you end up with effectively more code, but this code doesn't need to dynamically check the type being used.
@@ccgarciab Thank you!
Why don't people come out and say that traits are like interfaces in other languages?
Wow I like this kind of comparative learning very much and is very easy to gain all the information and adapt from a language i already know Insted of learning the whole thing again
dude yesterday I realized that PHP has traits too and is nice the way they implemented it
also "apparently" PHP is a strongly and static typed language
Great video! I'm currently studying Java and learning about different language in comparison to Java is amazing!
I don't understand your sentence at 3:53: "imagine we had a library which exposed the Animal trait, so that other developers can implement custom Animals. In that scenario we would had no way of knowing what concrete types implement our Animal trait. Because of this we would want to use trait objects". In most scenarios it is perfectly possible to use generics because all libraries are compiled together. Most of the time it is much more simple to use generics and trait objects should only be used as a last resort. Your vector example is a good use case for that. Another use case would be to use trait objects for returning a dynamic trait from a function. But then again you could use Enums for that. A third use case would be using the Error and Any traits from the standard library.
I assume that "plug-in" was intended there.
This video is so on point! Congrats! I was thinking about this past days and the video answered all my questions.
The generic function can be rewritten as:
fn print_animal_name(animal: impl Animal) {...}
Your video is much more easy to understand than the official book! Thanks!
amazing comparison , keep it up
These videos are just fantastic. You clearly have in-depth knowledge of Rust and computer science.
The topic of this video is probably the one that I have struggled most with regarding Rust.
Where do we draw the line between what we should do and what we can do? I was going down the path of implementing encapsulation using enums and match statements, the issue with this approach is that now I have code representing each struct type spread across many places. Your recommended approaches in this video avoid that, but we are ending up with pure functions instead of struct based methods. It is still not clear what the recommended approach is.
Some side notes:
* I keep running into situations where it looks like traits would be a lot easier to use if they included struct properties. I would allow me to create default implementations without having to provide methods for manipulating the properties.
* I have a small suggestion regarding your videos. If you paused for just one more second after you have completed an example before switching away from the code, then it would be easier to stop the video and read through the code. I often find that I have to go back and find the exact frame where everything is done so that I can read through the code, this would just make it easier and not add a lot of time to the video.
While the compiler where expand the function for each concrete type you use to call this function, this doesn't mean you have to know ALL concrete types you might use in the future. If your Animal trait is available via a library I still can implement my own type that implements Animal and call the function and the compiler (at this moment) will still generate the correct function in my binary (not in the library).
This approach is way more efficient than actually using dynamic dispatching, the only down side is that it produces a bigger binary file.
This is similar to Protocols in Swift.
Awesome explanation with examples! Great job dude!
Best Rust channel on TH-cam.
I program in C++ as in Rust. Should I change?
I wish I could like this video more than once.
Traits are like Java interfaces. When you try to create inheritance with traits, is unavoidable to duplicate code, like "impl Animal for Human" and "impl Animal for Dog". With inheritance, you can inherit not only functions, but attributes.
The classy OOP has an advantage (I know little about Rust. Correct me If I'm wrong). That is, we know what methods are available for this class. But in the struct based Rust, we don't know what method it offers. If the method is a common one, then we have to guess if that is already available or not. Or we have to implement it ourselves, e.g. to_string() method.
Amazing, so much content in under 6 minutes
This is a tweet size cheatsheet for Java VS Rust !! Awesum
comparing inheritance with traits is a bad comparison. Traits are much rather comparable to interfaces.
You should push instances into your Animal vec during instantiation, passing in the Animal vec.
Is using nested structs okey way to implement inheritance? Or is it impacts performance?
It doesn't impact performance. It's essentially how OOP languages implement inheritance under the hood.
If performance is the issue use generics instead of dynamic as vtable lookups cost at runtime where as generics just compile down to a jmp call. Nesting structs is absolutely fine and is usually faster in rust than other OOP languages as more sized objects can be determined at compile time
Does this mean a Vector cannot own the Animals it contains because it only has references?
its probably better to compare this to c# and use interfaces instead of abstract class - there is a lot of similarity between this two
1:00 now you have a Default trait
As always this is great! But can you also post the code as it would be nice to be able to go through it on the side, regardless of how contrived the examples are?
really enjoyed this comparation even though i am not learning rust lmao. i should tho
I really liked this style of video, super dynamic informative and with examples!
First amazing video thanks!
great video, very helpful mate. Thank you
If this had been called "Interfaces vs Traits" the video would've been about 30 seconds long; they're the same thing.
How to download this code
It's good solid content. Thumbs up dude
Thank you
Generics and polymorphism serve different purposes. They seem similar on the surface, but they are not substitutes for one another. Think about it. Java already has polymorphism, why would it introduce generics? Generics is for a particular algorithm that applies to different types. Polymorphism is more about a class of behavior where the algo impls can be different.
i love your videos and your voice
Rust is data driven afterall
well, that was rapid fire but basically pretty good
but it didn't bring up Java interface and how it has a similarity to traits and of course Java also does generics
IOW, this subject would need more time/detail to do a more thorough comparison of Java class to Rust trait
but for something so brief it was pretty good
'Interface' in Java is essentially interchangeable with 'Trait object' in Rust. Any `dyn Foo` is the same as IFoo would be in Java
720p? cool!
oops
Am I stupid? or is this shit complicated? I've been a developer for 4 years and I'm questioning my career choices, haha.
The first programming tutorials I ever followed were by @thenewboston (Bucky Roberts). I have never since been able to find tutorials that were as clear and to-the-point. Until now!
Thanks for the work you put into these, it is greatly appreciated. 😄