I'm genuinely curious - Why do you keep promoting the free cheat sheet on every. single. one. of. your. videos? Don't get me wrong, you make good content and your cheatsheet is really good, so I do appreciate that, but it's always those 5 seconds in your videos that I have to mentally ignore because I already know about it.
@@olivarra1 To get to the cheat sheet, you need to give an email and name. He's getting a lead in return (that may be used for inbound marketing). You "pay" with your lead info.
I loved the fact that he makes things that look intimidating to a new learner much easier by diving straight right into it. He doesnt beat around the bush, too, no unnecessary bs. Only what is needed.
Don't skip deserialization on a default value by default. It's bad practice, rather point the default parameter of the serde attribute to the default function. That way you can still deserialize a value if it's present but default when it's not.
Also it's not always good to implement default trait, because sometimes a type is expected to always hold a non-trivial value. Users can use Option if they really need default value
@@Андрей-ю2р6л @user-ne1nw6hw2q So for example, a http status code shouldn't implement default trait because 0 is not valid http status, am I correct?
The title is meant to catch your attention. It's hyperbole. Yes, library authors shouldn't implement the traits if they have good reason not to. Otherwise they should keep them in mind.
You should also derive Copy as well as Clone if the type you're exposing is supposed to be copied (like no heap allocated things like vecs or strings will be added to it in the future), and also should always add it to all basic enums that don't store any data. serde serialize and deserialize should probably be behind an optional feature, because not all people need serde
Hey, this is nth video from you that I am watching and I just want to say thanks for all this content. I have been on my Rust learning journey for a while and only recently am I feeling productive enough in my project. There are still tons of things to learn but Rust makes getting started much easier than I would have expected from a systems language.
Just so you know: The J and Gj in Jon Gjengset are soft. It's pronounced more like "Yon Yengset". Not that I blame you, I don't expect people to know how to pronounce names from a language they don't know.
@@31redorange08 Names in particular aren't that easy to look up. Regular words you can find in dictionaries, and some dictionaries have pronunciation guides. But proper nouns is not so easy.
So basically I can have one struct and trait along with it implementation block. Now I can use this trait implementation on the other struct and override the base trait if I want by creating impl block and change the functionality in it. I'm new to rust and exploring how to have inheritance like functionality in rust via composition. I require some good references as I can't find many good example anywhere
I thought the same. I'm wonder if it could be implemented as feature. If feature e.g. thread_safe is active use Arc otherwise Rc. I think, its quite a common problem. Is a standard solution for that in Rust?
I feel like it's better to have separate types for atomics since they're a bit slower. Example: pub struct User { ... db: Rc, } pub struct AtomicUser { ... db: Arc, }
@@LimitedWardyou will use first or second struct. The way it was shown on video, you will be obligated to use Arc type, which is slow. If user don't need arc, it must simple use "User" type, as commented above, else it must use second type.
Bogdan, at 6:55 you some how abruptly cut you video and jumped to serde topic without showing that Arc fixed the issue or showing any consequences of changes from Rc to Arc which feels a bit weird and unfinished. Also you haven't present any solution from the John's book. JFYI. Also you touched very nice topic about non-sendable types. So, I have a question. What if you have a type which need to be Send-able, like your User to be used in e.g. Axum, but you don't own it and it contains Rc which makes it non-sendable. What would be a solution to make such type sendable?
Always great vidéos as always... I see many usefull addine plugins on vs code or the terminal (autocomplete) can you give us some of them ? Or do a video about them.
I’m not too wild about your use of the term “should” in this video. Fine otherwise, but Rust has so many targets and use cases where you definitely shouldn’t use ARC instead of Rc or waste time including Serde support (embedded comes to mind), that laying down these things as absolutes to newbs without caveat is, imo, kinda harmful.
Please don't blindly derive Default unless the resulting value actually makes sense in the context of your type (e.g. if you have an identifier type Default with an empty string makes no sense).
@@lua-nya STD used to stand for subscriber trunk dialling, which is how phone lines used to handle out of area calls. He's clearly laughing at the juxtaposition of the "old school" phone lines with the "new kid on the block" Rust.
As a user of the lib, I'm concerned about code bloat that comes with libs. The author of the lib ASSUMED I will need it. What if I don't use any of these Debug, Sync etc in my code but they still get imported with the lib? Will rust compiler cut them out from my binary if my code doesn't use any of these derived traits?
Send & Sync are just marker traits as far as I am aware (no actual functionality, just flags that tell the compiler that certain multithreading things are safe). As for the others, the compiler is based on LLVM and _should_ automatically remove unused code from the compiled output (at least in release builds). So you should be good.
@@AshtonSnapp I'm not sure they are just marker traits. I think the macro literally embedds trait implementations into your code like any other macro does. So you end up with the implementation for Sync, Debug etc.
Sync is different from debug though, it doesn't have any associated methods to be added to a binary. The only place the trait could be used is by the compiler when type checking functions, it won't exist at any lower levels. Traits with associated functions or values like debug are a little bit different, but still should have their functions removed if they're unused
Unfortunately, there is no easy way to have Debug trait implemented for a struct or enum, containing function type. JS, as opposite, does have it by default.
I know it's a convention in tech instructions to use the type of something as the name, but it's a terrible convention that makes reading and interpreting difficult for beginners. I stopped watching the video around 1:20 when I saw the implementation of the User type was named 'user'. Put another way, the line let user: User = User { may as well say, "bar bar bar bar bar bar bar bar bar bar bar" for all of the nuance it provides. This isn't BrainF**k, after all. Please, for the love of clarity, stop using the same name for types and their implementations. Give us tangible, meaningful examples. Like the type is "Vehicle" and the implementation is "car", or type is "Animal" and implementation is "dog", or whatever, just not "Thing" and "thing". It's bad enough that the documentation gives "path" as both a crate and a string name in the one example: use std::path::Path; ... let path = Path::new("./foo/bar.txt");
📝Get your *FREE Rust cheat sheet* :
www.letsgetrusty.com/cheatsheet
No
I'm genuinely curious - Why do you keep promoting the free cheat sheet on every. single. one. of. your. videos?
Don't get me wrong, you make good content and your cheatsheet is really good, so I do appreciate that, but it's always those 5 seconds in your videos that I have to mentally ignore because I already know about it.
@@olivarra1 To get to the cheat sheet, you need to give an email and name. He's getting a lead in return (that may be used for inbound marketing). You "pay" with your lead info.
I'm not giving you my email address
I loved the fact that he makes things that look intimidating to a new learner much easier by diving straight right into it. He doesnt beat around the bush, too, no unnecessary bs. Only what is needed.
8:20 Just wanted to notice that serde can skip field db because Db implements Default trait, otherwise would be compile error
You can also configure serde to call a function that returns that type
Don't skip deserialization on a default value by default. It's bad practice, rather point the default parameter of the serde attribute to the default function. That way you can still deserialize a value if it's present but default when it's not.
Your library shouldn't implement Send + Sync if it doesn't make sense. Users can wrap T in Arc if they really need it.
Also it's not always good to implement default trait, because sometimes a type is expected to always hold a non-trivial value. Users can use Option if they really need default value
@@Андрей-ю2р6л @user-ne1nw6hw2q So for example, a http status code shouldn't implement default trait because 0 is not valid http status, am I correct?
The feature flag approach is beautiful - a real have your cake and eat it too moment
Probably the only trait here that should always be implemented is Debug. Library authors can have good reasons for not implementing the others.
The title is meant to catch your attention. It's hyperbole. Yes, library authors shouldn't implement the traits if they have good reason not to. Otherwise they should keep them in mind.
Thank you so much for this video: you made me add a bunch of feature flags and a new release for one of my crates, purely inspired by this content.
Thank you, great video and I'm really glad you showed how to feature-gate serde.
You should also derive Copy as well as Clone if the type you're exposing is supposed to be copied (like no heap allocated things like vecs or strings will be added to it in the future), and also should always add it to all basic enums that don't store any data.
serde serialize and deserialize should probably be behind an optional feature, because not all people need serde
> serde serialize and deserialize should probably be behind an optional feature, because not all people need serde
8:34
Noob here. Super cool use of cfg attributes and features! This languages get cooler everyday (that I learn more about it)
Hey, this is nth video from you that I am watching and I just want to say thanks for all this content. I have been on my Rust learning journey for a while and only recently am I feeling productive enough in my project. There are still tons of things to learn but Rust makes getting started much easier than I would have expected from a systems language.
Glad I could help!
amazing in a nutshell. this is incredible how I have less fear programming in rust traits now
Rustacean army come in! 🦀🦀🦀
Just so you know: The J and Gj in Jon Gjengset are soft. It's pronounced more like "Yon Yengset". Not that I blame you, I don't expect people to know how to pronounce names from a language they don't know.
Good to know, I didn't know that too.
Well, he has access to the internet to look it up.
@@31redorange08 Names in particular aren't that easy to look up. Regular words you can find in dictionaries, and some dictionaries have pronunciation guides. But proper nouns is not so easy.
Great video. Thanks for your efforts. I learn a lot from you.
So basically I can have one struct and trait along with it implementation block. Now I can use this trait implementation on the other struct and override the base trait if I want by creating impl block and change the functionality in it. I'm new to rust and exploring how to have inheritance like functionality in rust via composition. I require some good references as I can't find many good example anywhere
Very nice explanation of feature switches there
8:10 why not use a raw string literal (r#"..."#) for `user_str`?
Using Serde to apply strict typing to JSON input strings so easily is BY FAR the greatest value I've received from this video. Way to bury the lead! 😅
Isn't it inefficient to use Arc where Rc would work? That should be mentioned, since this is not a free modification.
I thought the same. I'm wonder if it could be implemented as feature. If feature e.g. thread_safe is active use Arc otherwise Rc. I think, its quite a common problem. Is a standard solution for that in Rust?
O maybe just use generic type parameter for pointer type. With default Rc.
Also, Copy instead of Clone if your type can implement it!
Wow, I was implementing PartialEq manually with match cases
I only just realized that serde is a portmaneau of serialize-deserialize.
8:27 Why does It show 2 users printing in the log?
What extension/settings do you use to get errors typed like that while coding?
Error lens
VSCode has an official Rust extension.
@@prajwalchapagain Thanks!
nice vid, one question, whats that extension called when the red text is being shown?
do you have to derive each time?
I feel like it's better to have separate types for atomics since they're a bit slower.
Example:
pub struct User {
...
db: Rc,
}
pub struct AtomicUser {
...
db: Arc,
}
Wouldn't you be losing even more speed when having to switch between types?
@@LimitedWard What do you mean by switching between types?
@@LimitedWardyou will use first or second struct. The way it was shown on video, you will be obligated to use Arc type, which is slow. If user don't need arc, it must simple use "User" type, as commented above, else it must use second type.
You could use a generic
So, If you don't own Role struct, how can you implement debug/clone/xyz trait?
Bogdan, at 6:55 you some how abruptly cut you video and jumped to serde topic without showing that Arc fixed the issue or showing any consequences of changes from Rc to Arc which feels a bit weird and unfinished. Also you haven't present any solution from the John's book. JFYI. Also you touched very nice topic about non-sendable types. So, I have a question. What if you have a type which need to be Send-able, like your User to be used in e.g. Axum, but you don't own it and it contains Rc which makes it non-sendable. What would be a solution to make such type sendable?
amazing video, keep it up. I was about to comment on the feature flag for serde!!
Always great vidéos as always... I see many usefull addine plugins on vs code or the terminal (autocomplete) can you give us some of them ? Or do a video about them.
You are really doing great work! do you have a Udemy course?
I NEED HELP! how do i use a code written in rust?
YT is not a good forum to get help with code.
Can’t rust provide these traits by default?
this was awesome, thank you :)
You are The MAN!
I’m not too wild about your use of the term “should” in this video. Fine otherwise, but Rust has so many targets and use cases where you definitely shouldn’t use ARC instead of Rc or waste time including Serde support (embedded comes to mind), that laying down these things as absolutes to newbs without caveat is, imo, kinda harmful.
Super useful and helpful, thanks!
love this type of videos. thanks
Please don't blindly derive Default unless the resulting value actually makes sense in the context of your type (e.g. if you have an identifier type Default with an empty string makes no sense).
1:12 how are you making these codes coming to screen like that?
I'm still laughing at STD traits....I know what it means... but it's so funny anyway...
Somehow I understand what you mean but not why you find it funny.
@@lua-nya STD used to stand for subscriber trunk dialling, which is how phone lines used to handle out of area calls.
He's clearly laughing at the juxtaposition of the "old school" phone lines with the "new kid on the block" Rust.
@@lua-nya I agree.
@@tbird-z1r Well thank you for the explanation, now I understand.
Sexually transmitted diseases
Thanks! great explanations!
Excellent video 👍🏼
As a user of the lib, I'm concerned about code bloat that comes with libs. The author of the lib ASSUMED I will need it. What if I don't use any of these Debug, Sync etc in my code but they still get imported with the lib? Will rust compiler cut them out from my binary if my code doesn't use any of these derived traits?
Send & Sync are just marker traits as far as I am aware (no actual functionality, just flags that tell the compiler that certain multithreading things are safe). As for the others, the compiler is based on LLVM and _should_ automatically remove unused code from the compiled output (at least in release builds). So you should be good.
@@AshtonSnapp I'm not sure they are just marker traits. I think the macro literally embedds trait implementations into your code like any other macro does. So you end up with the implementation for Sync, Debug etc.
Sync is different from debug though, it doesn't have any associated methods to be added to a binary. The only place the trait could be used is by the compiler when type checking functions, it won't exist at any lower levels. Traits with associated functions or values like debug are a little bit different, but still should have their functions removed if they're unused
@@CalebTerryRED Thanks for explanation. One concern. Should? Or Will be removed? :)
@@JS-fd5oh should and will be removed.
I actually tend to look for ::new instead of Default ... but I guess ::new without any args is Default LOL
any tips on that @letsgetrusty ?
Society when rust adds Debug to the list of default traits
thank you 👍
Unfortunately, there is no easy way to have Debug trait implemented for a struct or enum, containing function type. JS, as opposite, does have it by default.
Is this really? I do remember I implemented a trait for a foreign type these days, for testing a concept that I had in mind about extension functions
You must have wrapped it as it's not possible
@@workflowinmind
No, I really did not wrapped it, really.
@@workflowinmind
You can try it for yourself:
```rust
trait StringExt {
fn print_it(&self);
}
impl StringExt for String {
fn print_it(&self) {
println!("It is: {}", self);
}
}
fn main() {
let msg = "Hello, World!".to_string();
msg.print_it();
}
```
@@diadetediotedio6918 I think he said foreign traits AND foreign types, if you have either of them locally defined you can implement it.
@@LawlessSentry
OOO, that makes sense, thanks! But why is this the case?
I was working on a similar video :D
Now people are telling me to exposing my STDs.. smh
Good video 👍
It was a nice and easy video until you started with serialization code.
Drop the music.
Adding unnecessary traits can really slow down compile times.
Yeah first compile time is slow
unbelievable
I know it's a convention in tech instructions to use the type of something as the name, but it's a terrible convention that makes reading and interpreting difficult for beginners.
I stopped watching the video around 1:20 when I saw the implementation of the User type was named 'user'. Put another way, the line
let user: User = User {
may as well say, "bar bar bar bar bar bar bar bar bar bar bar" for all of the nuance it provides. This isn't BrainF**k, after all.
Please, for the love of clarity, stop using the same name for types and their implementations.
Give us tangible, meaningful examples. Like the type is "Vehicle" and the implementation is "car", or type is "Animal" and implementation is "dog", or whatever, just not "Thing" and "thing".
It's bad enough that the documentation gives "path" as both a crate and a string name in the one example:
use std::path::Path;
...
let path = Path::new("./foo/bar.txt");