Dude, I think your channel is amazing, I can't believe people still deal with the same memory errors on C and C++, it's time to switch to an actual modern language. And I'm glad that people like you are making this community one of the best among the programming languages.
Wo wo wo, hold your horses, No doubt Mr. Bogdan is one of his kind and I admire his contribution, but chances are the operating system that you watching and commenting here is implemented somehow in its core with C and C++, sooner or later Linus Torvalds will implement Rust into one of his upcoming kernels
Wow dude, been using a book to learn Rust and each chapter was just bloat of unnecessarily complicated examples. You explanation is just spot on! Please continue updating the playlist, even after The Rust Lang Book is done. Maybe a code-along with a webapp or a terminal utility.
For the if let syntax, it also reduces the amount of identantion used, e.g: match some_val { Some(val) => { use(val); }, _ => (), } if let Some(val) = some_val { use(val); }
I really like the way you explain concepts of Rust. I have been reading several books on Rust and enrolled for courses on the same but I find your explanations being concise and well delivered. I rate you videos on learning Rust at 9/10. I have only two criticisms 1) Fast forwarding sections of the video where you type, I think it is okay for us to follow you type at natural speed as it takes time to absorb and process the information taught. I find myself having to pause or even rewind to better understand these sections. 2) The background music, I think background music in educational videos cause some distraction. The inclusion of background music seems to be a common trend on TH-cam videos, but I would be had pressed to see a college class being taught as music plays in the background. The background music in your videos seems to oscillate in volume with a frequency of 1 Hertz. From the comments, it seems I am the only one finding these two challenges. Probably this requires more investigation. Perhaps someone with training and experience in education and learning can provide their input on this matter.
Thank you for the feedback! I agree that natural typing is better for learning. Similar to professors writing on the chalk board, it gives time to process the information. I will improve this aspect of my videos in the future. The background music should be improved in later videos although I didn't remove it altogether. That's something I will consider doing.
@@letsgetrusty I don't have issue with speeding up typing, but when deleting and writing new code to do the same (or similar), as around 3:00, it would be better to comment out the old code, write the new code, and only then delete the commented out code. So we can compare codes, and see that these codes do the same thing.
I've seen syntax similar to 'if let' in other languages. It makes heaps more sense if you consider an example of a bound variable: if let Some(x) = some_value { ... } You're conditionally defining "let x" to be the bound value within the following code block if it matches the specified variant.
11:30 tested, it works, but is confusing, and I still don't know any case where you would specifically need that syntax, but this also works: if Some(3) == some_value { /* do something */ }
It was a pretty bad example. `if let` is mainly useful for when you have an enum that holds some inner value in some variant, and you want to access the inner value on _that specific_ variant. For instance: enum MyEnum { A(i32), B(u32) } let my_enum = MyEnum::A(0i32); if let A(inner_value) = my_enum { println!("my_enum is the A variant with {} as the inner value", inner_value); } A similar thing is `let else` which lets you _bind_ the inner value of some variant to a variable, or run some other code if the enum is _not_ that variant, like so: enum MyEnum { A(i32), B(u32) } let my_enum = MyEnum::A(0i32); let MyEnum::A(inner_value) = my_enum else { panic!("my_enum is the B variant, need the A variant"); }
I agree with your thoughts about if let syntax: It is confusing, especially if you look at the "if let" examples mixed with else, else if let, combinations in the book. I bet an Effective Rust book would contain an item "Don't use if let, use match instead.
if let is very useful (succinct) if you use it correctly. if let Some(item) = vector.get(20) { // or any Option returned by a function // do something with item } That's what if let is for.
3:33 - That's not an anonymous struct, since there's no anonymous structs in Rust. In the Rust Book it's described as "has named fields like a struct does" and in the example it's commented as "c-like structures".
11:27 Couldn't you have used a normal if-statement in this case? You can always compare against a specific value like _Some(3),_ the "if let" syntax only comes in handy when you want to catch any _Some(_)_ or want to reuse the inner value that you're comparing against, for example: if let Some(value) = some_value { println!("The value is {}", value); }
Thank you for this comment. I immediately tested if some_value == Some(3) { ... } while following along with this and found it worked just fine, so I was wondering what the purpose of "if let" could be. Your explanation clarified it for me instantly.
Thank you. I was thinking something similar and this clears it up well for me. This is a tool I've been looking for in a typed language for a while now. It seems like I shouldn't have delayed learning rust so long.
Yeah the example wasn't clear this time, the book showed a better example. if-let is used for pattern matching, not for value matching, in that case, an if would be just fine.
Great videos! You explain the concepts really well. Minor thing I recognized: I think you forgot the '&self' as an argument for the method 'fn some_function' at 4:14.
nah, he just created an associative function, but honestly his explanation of impl assumes you know about structs, and wasn't very cohesive. Not to mention he didn't really explain very well how to access pieces of information from enums. I like most of this guy's videos, but this one didn't hit the mark at all.
Wow, it's interesting that you explain a lot of complex concepts very simply, but you find "if let" confusing. Personally, it's my favorite pattern matching feature, and I think there's a simple way to look at it. It's just a pattern matching (if) + descructuring (let). In your example you don't use destructuring, which is probably why it seems confusing: if let Some(3) = ... But if you consider an example where you need some heavy duty destructuring, it starts making a lot of sense: if let Some(Connection(Status("OK"), IpAddr(ip), Port(port))) = wait_connection() { println!("Connected to {ip}:{port}") } obs: The Connection struct is far from optimal, but it gets the point accross.
The `if let` syntax is confusing to me too, but I think I'm finally starting to get it after I realized that my problem was actually that I didn't understand what `let` means well enough. I thought it just bound the LHS to the RHS, but it's more powerful than that. Conceptually, `let` just fills in the blanks on the left of the `=` to make the left and right sides of the `=` match. So `let x = 3;` is filling in the "blank" (in this case `x`) with a `3` to make the equality hold. More complicated is `let Some(x) = Some(3);` but in this case `x` gets bound to `3` as well. The `if let Some(x) = optional_function()` is true if `let` can do its job of filling in the "blank" `x`. If `optional_function()` doesn't return something of the form `Some(y)`, then `let` fails; otherwise, `x` gets bound to `y` and we can do stuff with `x`. This article really helped me understand it better: h2co3.github.io/pattern/.
Very confusing. Even after googling I don't understand why they chose this syntax. `if let` is pattern matching, so in a sense ìf let` is to `match` what `if` is to `switch`. Except that rust merges match and switch into the same statement, making this even more confusing.
i agree that it's weird, but assignment makes sense because it also binds the pattern identifier if let Some(val) = func() binds `val` to the value inside Some(_) but does nothing if it is None, unless you have an else clause same deal with while let
Is a good developer doesn’t use strings for an IP address but just an u64 that’ll cover the IPv4 32 bit addresses and the IPv6 64 but addresses ;) In the socket layer they are actual 32/64 addresses :) But I catch your point. Great demo.
Good to know that it's not just me that is confused about if let. Match statements are so much more readable. You don't really declare anything new even though you are using the let key word, and just like the match, whatever is in the Some() is scoped. I almost want to go back to Typescript now.
You are declaring something new, the example in the video was just bad. If-let checks the variant of the enum, destructures the enum if it's of the specified variant (ie Some(T) for Option), then binds the inner value of the variant to the variable name within the variant's paranthesis within the scope of the if-let block. The "let" signifies that you're going to be destructuring the enum and binding the inner value to a new variable. Say you had the below function: fn main() { let my_string: Option = Some(String::from("Hello, World!")); } And you wanted to do print the String behind the Option, _if_ there is a String behind the Option. To do so, you'd do this: fn main() { let my_string: Option = Some(String::from("Hello, World!")); if let Some(the_inner_string) = my_string { println!("The string is: {}", the_inner_string); } } It's basically a shortcut for the below match statement: fn main() { let my_string: Option = Some(String::from("Hello, World!")); match my_string { Some(the_inner_string) => println!("The string is: {}", the_inner_string), None => {} } } The match statement has an unnecessary branch to cover the None variant, so if-let lets you get rid of that and _only_ use the Some variant.
Using match statement to calculate coin value seems to be overkill. Is there a way to keep coin value inside enum? Like in C/C++ we write enum { nikel = 1, dime = 10 ... }
11:27 It seems like the syntax is basically a simple if condition with a variable assignment embedded into it, declaring that variable to only be within the scope of the if block and making an assumption on the value of the variable which is guaranteed by the if check. It's doing two things at once and the one depends on the other (hence it can't be in a separate statement). I'm not sure of a better syntax of the top of my head, though when I first saw that just now I'll admit I was a bit baffled by its syntax.
I looked up another example where they actually used the number inside the option enum, `if let Some(i) = some_value`, which made it much better. I haven't written a line of code in the language yet, but it seems like you shouldn't need an if-let expression if you are doing an exact match. Then a simple equality check ought to work (right? Yeah, I should have read some more comments before I made my own).
8:40 if I use println!("{ }",value...) , the number"25" would be printed out, but if I type the value(....) function directly like you did in the video , the numbe"25" wont be printed out like your example, so everytime I need to add println!("{ }", value ..) in order to print out the number as well ? and Why the number wont be printed out if I directly type the value(...) function ? Thank you for your video !
In my example the state is printed out, not the value, and I use the println!("{ }", state) syntax. This syntax is required because the first argument must be a string literal.
Yes. An easy example is a token within an AST. An AST can have possibly dozens of types of tokens, but you may want to abstractly refer to any one of those types as _just_ an abstract token. In other languages you may model this with a class hierarchy via inheritance, whereas in Rust you may model this with an enum where each variant is a type of token. One variant is a '>' token, another variant is a '>>' token, and a third can be a generic character token to support identifier characters (ie A-z, 0-9 and _). The '>' and '>>' tokens don't need to store any inner values since you have enough information from the variant alone ('>' is a single >, '>>' is two >'s in a row), but the generic character token needs to store the specific character code of the token, so you'd have that variant store an inner char.
At the rate this is going I'm frankly terrified at the concept of there being 44 videos. If this was C++ (which I'm fluent in) at this rate I'd expect maybe 20 videos.
With enums they kinda confuse me when you have enum IpAddrKind{ V4, V6 } then you create instances of these enum types what does that actually do? let four: IpAddrKind=IpAddrKind::V4; like what does ^^ even mean really? what can I do with that info. Great video btw I just find this topic confusing for some reason.
Internally, Rust uses a special tag to differentiate between the variants of each enum. Basically, imagine if it looked like this: enum IpAddrKind { V4, // tag = 0 V6 // tag = 1 } When you do this: let four = IpAddrKind::V4; What you're doing is constructing a value that holds the tag of the variant you've selected, sort of like so: let four = /* IpAddrKind { tag: 0 } */; When you do this later on in the code: match four { IpAddrKind::V4 => /* something */, IpAddrKind::V6 => /* another thing */, } Rust emits code equivalent to: if /* four.tag */ == 0 { /* something */ } else if /* four.tag */ == 1 { /* another thing */ } To choose which branch to execute based on the tag. Enums that store data within each variant work the exact same, but also place the data alongside the tag, choosing a specific order based on which is smaller between the tag and the data, since Rust can change the order to potentially reduce the size of the whole enum type. Essentially, this is what it'd look like: enum IpAddrKind { V4(u8, u8, u8, u8), // tag = 0, memory layout = { u8, u8, u8, u8, tag } V6(String) // tag = 1, memory layout = { String, tag } } In the above code the quadruplet of u8's and the String occupies the same space in the enum type's memory layout, as Rust knows that you will only use _either_ the quadruplet of u8's _or_ the String _and never both at the same time,_ letting it safely reuse that space to reduce the size of the enum type (look up unions in C, Rust treats the per-variant data as a union). Because Rust has the tag, it can know what variant you're using and is able to safely let you access the per-variant data, like so: match four { IpAddrKind::V4(a, b, c, d) => /* something that uses a, b, c and d */, IpAddrKind::V6(s) => /* another thing that uses s */ }
In 9:50, its posible to do the same func but instead of taking a i32 takes a ? I did this but didn't work fn _plus_one(x: Option) -> Option { match x { Some(i: i32) => Some(i + 1), _ => None, } }
Yes. Those are type hints and are driven by type inference, since Rust and the IDE are both smart enough to figure out what the type is based on what functions are used and where the value originates from.
Why can't we iterated over each of the variants of an enum ? Seems like such an obvious and convenient thing to want to do. Or does it mean I am thinking about and possible using enums in the wrong way ?
You probably are. It doesn't make any sense to iterate over the variants of an enum, as the variants themselves aren't useful. Enums are used to describe types that can take multiple forms, and each variant describes a particular form that the type can be (think an abstract token within a code parser, where each individual type of token is a separate variant). When you construct an instance of the type, you are constructing an instance of _a specific form_ of that type, which you do by selecting _a specific variant._ As such it doesn't make any sense to iterate over the variants of an enum here, either, as you'd basically be taking an instance of a type that is in one form (say Some(T) for an Option) and trying to force it to be another form (say None for that same Option). The instance of that type is in that specific form for a reason, so trying to force it to be another form is problematic and has a very real chance of breaking things (especially if the type is storing any inner data).
Something I don't understand about the examples in this chapter is why wouldn't you just say "let five = 5)" then do "let six = plus_one(five)". is there some reason you would want to use Some(5) there?
Convert a go developer? Oh shit, not another sw eng rivalry :P that's it, in the great tradition of evil emacs, I'm going to wrap all my Go up in Rust calls, and vice-a-versa.
Plain if statement seems to work just like if let. So why if let should/must be used instead? if some_value == Some(3) { println!("{:?}", some_value); }
The example in the video was bad. If-let is used for when you don't know what the enum variant contains (ie you don't know that it's Some(3)), but you want to access it and you know it has to be of a specific variant (ie Some(n), where n is the number you want to access). If-let basically binds the inner data of the enum variant to a local variable, letting you access it through that variable, like so: if let Some(n) = some_value { println!("{} + 10 = {}", n, n + 10); }
It was a bad example. The key point is that if-let lets you bind the inner value of the enum variant to a variable that's scoped to the if-let block, letting you safely access that inner value within the if-let block, since you've already checked that the variant is correct.
Yep. It’s almost word-for-word and example-for-example. I will admit, however, getting fed the chapter in 12.5 minutes is a lot faster than reading it myself. But that’s just for seeing the syntax. The diagrams showing the flow of data within memory is (imo) extremely important for understanding HOW rust works, which you don’t get in videos like these.
I'm still so confused by enums existing as a concept... I mean it's just a "legal" hardcode. Hardcode = bad code, enums != bad code. I don't get it, please someone explain this. I'm 1,5 in programing(C, JS, Python), almost a year of commertial expirience, and I've never used an enums. Literally. Why they are so functional in Rust? It really doesn't make any sence to me
What do you mean by hardcode? The awesome thing with Rust enums is that they're _not_ hard coded, they can accept and store variable values that originate from runtime code, in a way that lets you determine _what_ group of values the enum is currently storing. It's as if you took a union in C, added a tag that told you what variant the union is currently in, then sculpted the language around using that tag to make certain guarantees around the variant that the union is in when it's used in different contexts (pattern matching, if-let destructuring, let-else destructuring, etc). Take any usecase for a C union, add a ton of extra safety features on top that made it safer to use, then imagine the new usecases that would open up if you had that extra safety, and that's why they're so functional in Rust.
📝 Get your *FREE Rust cheat sheet* : www.letsgetrusty.com/cheatsheet
go developer here. Had to comment when I heard your little intro. Gotta say I'm loving rust. Already subscribed. Thanks for the awesome tutorial.
Dude, I think your channel is amazing, I can't believe people still deal with the same memory errors on C and C++, it's time to switch to an actual modern language. And I'm glad that people like you are making this community one of the best among the programming languages.
Appreciate the support Thiago!
Wo wo wo, hold your horses, No doubt Mr. Bogdan is one of his kind and I admire his contribution, but chances are the operating system that you watching and commenting here is implemented somehow in its core with C and C++, sooner or later Linus Torvalds will implement Rust into one of his upcoming kernels
@@MohammedYasinRashidI do believe that’s since been done no? 😅
With every subscription you convert a Go dev. xD
Your "convert a go developer" comment is priceless. I do love go...but as I learn more rust, I see less of a need/desire to use it.
Rust's enum are so amazing! My c++ mind is blown.
Wow dude, been using a book to learn Rust and each chapter was just bloat of unnecessarily complicated examples. You explanation is just spot on! Please continue updating the playlist, even after The Rust Lang Book is done. Maybe a code-along with a webapp or a terminal utility.
books are the most inefficient method for learning, as you say, absolutely bloated, they have pages to fill, its a pre 21st century learning tool
@@theLowestPointInMyLifedude meant the official rust documentation books which are not books
@@theLowestPointInMyLife Books are supposed to cover everything. It's not the author's fault if the reader is inadept at skimming the book.
It worked. I was a go developer, but I couldn't stand the garbage collection. So now I'm the rustacean!🙂
This was really helpful. Can't read the book rn. Nice to have a quick visual alternative
For the if let syntax, it also reduces the amount of identantion used, e.g:
match some_val {
Some(val) => {
use(val);
},
_ => (),
}
if let Some(val) = some_val {
use(val);
}
I really like the way you explain concepts of Rust. I have been reading several books on Rust and enrolled for courses on the same but I find your explanations being concise and well delivered. I rate you videos on learning Rust at 9/10.
I have only two criticisms
1) Fast forwarding sections of the video where you type, I think it is okay for us to follow you type at natural speed as it takes time to absorb and process the information taught. I find myself having to pause or even rewind to better understand these sections.
2) The background music, I think background music in educational videos cause some distraction. The inclusion of background music seems to be a common trend on TH-cam videos, but I would be had pressed to see a college class being taught as music plays in the background. The background music in your videos seems to oscillate in volume with a frequency of 1 Hertz.
From the comments, it seems I am the only one finding these two challenges. Probably this requires more investigation. Perhaps someone with training and experience in education and learning can provide their input on this matter.
Thank you for the feedback!
I agree that natural typing is better for learning. Similar to professors writing on the chalk board, it gives time to process the information. I will improve this aspect of my videos in the future.
The background music should be improved in later videos although I didn't remove it altogether. That's something I will consider doing.
None of those aspects bother me. Perhaps, I just got used to coding having earphones on (with doom eternal soundtrack being played).
I haven't found it to be an issue either, but maybe experiment-do a video two ways and see what people like?
@@letsgetrusty Yes, please remove the background music.
@@letsgetrusty I don't have issue with speeding up typing, but when deleting and writing new code to do the same (or similar), as around 3:00, it would be better to comment out the old code, write the new code, and only then delete the commented out code. So we can compare codes, and see that these codes do the same thing.
This channel is amazing, you explained and digested such a complex language well, thank you
You be starting beef lololol
Shots were fired
I've seen syntax similar to 'if let' in other languages. It makes heaps more sense if you consider an example of a bound variable:
if let Some(x) = some_value { ... }
You're conditionally defining "let x" to be the bound value within the following code block if it matches the specified variant.
It's a relief to know the if let syntax is confusing for you too, I find it so confusing too, the readability is strange
11:30
tested, it works, but is confusing, and I still don't know any case where you would specifically need that syntax, but this also works:
if Some(3) == some_value { /* do something */ }
It was a pretty bad example. `if let` is mainly useful for when you have an enum that holds some inner value in some variant, and you want to access the inner value on _that specific_ variant. For instance:
enum MyEnum {
A(i32),
B(u32)
}
let my_enum = MyEnum::A(0i32);
if let A(inner_value) = my_enum {
println!("my_enum is the A variant with {} as the inner value", inner_value);
}
A similar thing is `let else` which lets you _bind_ the inner value of some variant to a variable, or run some other code if the enum is _not_ that variant, like so:
enum MyEnum {
A(i32),
B(u32)
}
let my_enum = MyEnum::A(0i32);
let MyEnum::A(inner_value) = my_enum else {
panic!("my_enum is the B variant, need the A variant");
}
@@jcm2606 Ah! Thank you very much for the explanation!
As soon as you said there is no null in Rust my mind just exploded.
I agree with your thoughts about if let syntax: It is confusing, especially if you look at the "if let" examples mixed with else, else if let, combinations in the book. I bet an Effective Rust book would contain an item "Don't use if let, use match instead.
You can use a more straightforward if:
if Some(3) == some_value {}
if let is very useful (succinct) if you use it correctly.
if let Some(item) = vector.get(20) { // or any Option returned by a function
// do something with item
}
That's what if let is for.
Thank you for your hard work. Best Rust channel in my opinion. Keep it up!
3:33 - That's not an anonymous struct, since there's no anonymous structs in Rust.
In the Rust Book it's described as "has named fields like a struct does" and in the example it's commented as "c-like structures".
11:27 Couldn't you have used a normal if-statement in this case?
You can always compare against a specific value like _Some(3),_ the "if let" syntax only comes in handy when you want to catch any _Some(_)_ or want to reuse the inner value that you're comparing against, for example:
if let Some(value) = some_value {
println!("The value is {}", value);
}
Otherwise the content of that video was summed up really well, thank you
Thank you for this comment. I immediately tested if some_value == Some(3) { ... } while following along with this and found it worked just fine, so I was wondering what the purpose of "if let" could be. Your explanation clarified it for me instantly.
Thank you. I was thinking something similar and this clears it up well for me.
This is a tool I've been looking for in a typed language for a while now. It seems like I shouldn't have delayed learning rust so long.
Yeah the example wasn't clear this time, the book showed a better example. if-let is used for pattern matching, not for value matching, in that case, an if would be just fine.
Thanks for this comment. Was wondering why he didn't just use an if statement, and what the propose of if let really is. Answered both for me here.
Great videos! You explain the concepts really well. Minor thing I recognized: I think you forgot the '&self' as an argument for the method 'fn some_function' at 4:14.
nah, he just created an associative function, but honestly his explanation of impl assumes you know about structs, and wasn't very cohesive. Not to mention he didn't really explain very well how to access pieces of information from enums. I like most of this guy's videos, but this one didn't hit the mark at all.
as a C++ programmer of 9 years.... these videos are slowly converting me
Thanks for these videos they are great. The if let syntax looks familiar to c++ if init statements
Bro , you're doing god's work here
I think it would be awesome if you could provide a useful implementation for the enum method. Great content anyway
Wow. I love this series!
Love the flag on the background! God bless America and Rust🦀
Your channel in amazing. With love from Bavaria
Lol subbed because of the converting a go developer joke. Definitely hit home for me.
Wow, it's interesting that you explain a lot of complex concepts very simply, but you find "if let" confusing.
Personally, it's my favorite pattern matching feature, and I think there's a simple way to look at it.
It's just a pattern matching (if) + descructuring (let).
In your example you don't use destructuring, which is probably why it seems confusing:
if let Some(3) = ...
But if you consider an example where you need some heavy duty destructuring, it starts making a lot of sense:
if let Some(Connection(Status("OK"), IpAddr(ip), Port(port))) = wait_connection() {
println!("Connected to {ip}:{port}")
}
obs: The Connection struct is far from optimal, but it gets the point accross.
It should look like this:
if some_value matches Some(3) {
println!("three");
}
@@jabuci Yeah, that'd be easier to read!
Really like your videos, thanks for making them.
Thank you so much for the series, this is super helpful.
The `if let` syntax is confusing to me too, but I think I'm finally starting to get it after I realized that my problem was actually that I didn't understand what `let` means well enough. I thought it just bound the LHS to the RHS, but it's more powerful than that. Conceptually, `let` just fills in the blanks on the left of the `=` to make the left and right sides of the `=` match. So `let x = 3;` is filling in the "blank" (in this case `x`) with a `3` to make the equality hold. More complicated is `let Some(x) = Some(3);` but in this case `x` gets bound to `3` as well. The `if let Some(x) = optional_function()` is true if `let` can do its job of filling in the "blank" `x`. If `optional_function()` doesn't return something of the form `Some(y)`, then `let` fails; otherwise, `x` gets bound to `y` and we can do stuff with `x`.
This article really helped me understand it better: h2co3.github.io/pattern/.
This chapter made me understand why some Haskellers like Rust.
How are you getting the automatic typing in your IDE?
Match is so good, it is like switch on steroids
I really like this vedio, it makes sense more than just reading the book!
lol this video just repeats the Rust book chapter about enums. The code is the same, everything is the same
« Each time you subscribe, we convert a Go developer ». That was offensive. I felt that. 🥺
The "if let" syntax of Rust is rather confusing, we evaluate for equality using an assignment operator as opposed to an equality operator.
It is weird. Also can it have != operator or is it specifically = only.
Very confusing. Even after googling I don't understand why they chose this syntax. `if let` is pattern matching, so in a sense ìf let` is to `match` what `if` is to `switch`. Except that rust merges match and switch into the same statement, making this even more confusing.
@@wyattbiker Seems to be only =. I tried `if !(let Some( ....` and rustc said "let in this position is experimental. see github issue 53667".
i agree that it's weird, but assignment makes sense because it also binds the pattern identifier
if let Some(val) = func() binds `val` to the value inside Some(_) but does nothing if it is None, unless you have an else clause
same deal with while let
Im from Argentina. I don't know if you are saying "NOTA" in Spanish or "Note that". Thanks for your videos man. They are helpful and entertaining
I'm saying "note that"
I'm also confused with Chi Shi. Is it a Chinese girl or simply "cheat sheet"?
@@jabuci it could be a small Chinese cheat sheet, I suppose. Por que no los dos? amiright?
Is a good developer doesn’t use strings for an IP address but just an u64 that’ll cover the IPv4 32 bit addresses and the IPv6 64 but addresses ;) In the socket layer they are actual 32/64 addresses :)
But I catch your point. Great demo.
"everytime you subscribe, we convert a Go developer" had me cracking
Good to know that it's not just me that is confused about if let. Match statements are so much more readable. You don't really declare anything new even though you are using the let key word, and just like the match, whatever is in the Some() is scoped. I almost want to go back to Typescript now.
You are declaring something new, the example in the video was just bad. If-let checks the variant of the enum, destructures the enum if it's of the specified variant (ie Some(T) for Option), then binds the inner value of the variant to the variable name within the variant's paranthesis within the scope of the if-let block. The "let" signifies that you're going to be destructuring the enum and binding the inner value to a new variable. Say you had the below function:
fn main() {
let my_string: Option = Some(String::from("Hello, World!"));
}
And you wanted to do print the String behind the Option, _if_ there is a String behind the Option. To do so, you'd do this:
fn main() {
let my_string: Option = Some(String::from("Hello, World!"));
if let Some(the_inner_string) = my_string {
println!("The string is: {}", the_inner_string);
}
}
It's basically a shortcut for the below match statement:
fn main() {
let my_string: Option = Some(String::from("Hello, World!"));
match my_string {
Some(the_inner_string) => println!("The string is: {}", the_inner_string),
None => {}
}
}
The match statement has an unnecessary branch to cover the None variant, so if-let lets you get rid of that and _only_ use the Some variant.
Do you discuss Ownership with Enums in Rust on your channel? I just came from the book Imma be honest, I don't get it from there. Please help. Thanks!
I am sorry for my fellow Go developers but I have subscribed.
Best Line --- "Every time you subscribe we convert a GO developer."
Using match statement to calculate coin value seems to be overkill. Is there a way to keep coin value inside enum? Like in C/C++ we write enum { nikel = 1, dime = 10 ... }
11:27 It seems like the syntax is basically a simple if condition with a variable assignment embedded into it, declaring that variable to only be within the scope of the if block and making an assumption on the value of the variable which is guaranteed by the if check. It's doing two things at once and the one depends on the other (hence it can't be in a separate statement). I'm not sure of a better syntax of the top of my head, though when I first saw that just now I'll admit I was a bit baffled by its syntax.
I looked up another example where they actually used the number inside the option enum, `if let Some(i) = some_value`, which made it much better. I haven't written a line of code in the language yet, but it seems like you shouldn't need an if-let expression if you are doing an exact match. Then a simple equality check ought to work (right? Yeah, I should have read some more comments before I made my own).
@@SemiMono That's an error in this video. The if-let syntax should be used for pattern-matching not for value-matching
8:40 if I use println!("{ }",value...) , the number"25" would be printed out, but if I type the value(....) function directly like you did in the video , the numbe"25" wont be printed out like your example, so everytime I need to add println!("{ }", value ..) in order to print out the number as well ? and Why the number wont be printed out if I directly type the value(...) function ?
Thank you for your video !
In my example the state is printed out, not the value, and I use the println!("{ }", state) syntax. This syntax is required because the first argument must be a string literal.
"Welcome to Rust channel. Be sure to subscribe cus everytime you subscribe we convert a Go developer"
How is it different from if (typeof x == "number") {} else {}?
So from what I understand an enum in rust is used if you need a type that has more than 1 variant of that type?
Yes. An easy example is a token within an AST. An AST can have possibly dozens of types of tokens, but you may want to abstractly refer to any one of those types as _just_ an abstract token. In other languages you may model this with a class hierarchy via inheritance, whereas in Rust you may model this with an enum where each variant is a type of token. One variant is a '>' token, another variant is a '>>' token, and a third can be a generic character token to support identifier characters (ie A-z, 0-9 and _). The '>' and '>>' tokens don't need to store any inner values since you have enough information from the variant alone ('>' is a single >, '>>' is two >'s in a row), but the generic character token needs to store the specific character code of the token, so you'd have that variant store an inner char.
At the rate this is going I'm frankly terrified at the concept of there being 44 videos. If this was C++ (which I'm fluent in) at this rate I'd expect maybe 20 videos.
Watch at 2x speed and it’s basically 20 videos
For C++ and all it's different versions, you need 200 videos :p
Very nice! Only weird thing is this `if let` syntax. Don't get why they designed it like that.
With enums they kinda confuse me
when you have
enum IpAddrKind{
V4,
V6
}
then you create instances of these enum types what does that actually do?
let four: IpAddrKind=IpAddrKind::V4;
like what does ^^ even mean really? what can I do with that info.
Great video btw I just find this topic confusing for some reason.
Internally, Rust uses a special tag to differentiate between the variants of each enum. Basically, imagine if it looked like this:
enum IpAddrKind {
V4, // tag = 0
V6 // tag = 1
}
When you do this:
let four = IpAddrKind::V4;
What you're doing is constructing a value that holds the tag of the variant you've selected, sort of like so:
let four = /* IpAddrKind { tag: 0 } */;
When you do this later on in the code:
match four {
IpAddrKind::V4 => /* something */,
IpAddrKind::V6 => /* another thing */,
}
Rust emits code equivalent to:
if /* four.tag */ == 0 {
/* something */
} else if /* four.tag */ == 1 {
/* another thing */
}
To choose which branch to execute based on the tag. Enums that store data within each variant work the exact same, but also place the data alongside the tag, choosing a specific order based on which is smaller between the tag and the data, since Rust can change the order to potentially reduce the size of the whole enum type. Essentially, this is what it'd look like:
enum IpAddrKind {
V4(u8, u8, u8, u8), // tag = 0, memory layout = { u8, u8, u8, u8, tag }
V6(String) // tag = 1, memory layout = { String, tag }
}
In the above code the quadruplet of u8's and the String occupies the same space in the enum type's memory layout, as Rust knows that you will only use _either_ the quadruplet of u8's _or_ the String _and never both at the same time,_ letting it safely reuse that space to reduce the size of the enum type (look up unions in C, Rust treats the per-variant data as a union). Because Rust has the tag, it can know what variant you're using and is able to safely let you access the per-variant data, like so:
match four {
IpAddrKind::V4(a, b, c, d) => /* something that uses a, b, c and d */,
IpAddrKind::V6(s) => /* another thing that uses s */
}
Thanks
In 9:50, its posible to do the same func but instead of taking a i32 takes a ?
I did this but didn't work
fn _plus_one(x: Option) -> Option {
match x {
Some(i: i32) => Some(i + 1),
_ => None,
}
}
6:50 error on assigning the None it looks like this error only for the newer version of rust
".. because every time you subscribe, you convert a Go developer.' lmao
Guys, when I see this ::Output I feel like go back to C, can someone explain? Does his IDE add these small/gray fonts or what?
Yes. Those are type hints and are driven by type inference, since Rust and the IDE are both smart enough to figure out what the type is based on what functions are used and where the value originates from.
Why can't we iterated over each of the variants of an enum ? Seems like such an obvious and convenient thing to want to do. Or does it mean I am thinking about and possible using enums in the wrong way ?
You probably are. It doesn't make any sense to iterate over the variants of an enum, as the variants themselves aren't useful. Enums are used to describe types that can take multiple forms, and each variant describes a particular form that the type can be (think an abstract token within a code parser, where each individual type of token is a separate variant). When you construct an instance of the type, you are constructing an instance of _a specific form_ of that type, which you do by selecting _a specific variant._ As such it doesn't make any sense to iterate over the variants of an enum here, either, as you'd basically be taking an instance of a type that is in one form (say Some(T) for an Option) and trying to force it to be another form (say None for that same Option). The instance of that type is in that specific form for a reason, so trying to force it to be another form is problematic and has a very real chance of breaking things (especially if the type is storing any inner data).
Something I don't understand about the examples in this chapter is why wouldn't you just say "let five = 5)" then do "let six = plus_one(five)". is there some reason you would want to use Some(5) there?
Why is it necessary to use String::from in structs and enums?
Because you need to convert the string slice (literal) to an std::String
I'm a GO dev, and that hurt my feelings lol
wow, you are the spitting image of that Bogdan guy, you should really check him out, he has a channel on youtube called "Let's get Rusty"
I Feel personally attacked after that intro cause I’m dropping go as my next language
I'm speedrunning your videos, this shows how much I hate C++
Nice series, but that weird background music/sound/repeating pattern is really putting me off.
Instead of using if let I could just say if x == Some(3) {...} so why use if let ?
Cause when you subscribe we convert a Go developer
Convert a go developer? Oh shit, not another sw eng rivalry :P that's it, in the great tradition of evil emacs, I'm going to wrap all my Go up in Rust calls, and vice-a-versa.
Plain if statement seems to work just like if let. So why if let should/must be used instead?
if some_value == Some(3) {
println!("{:?}", some_value);
}
The example in the video was bad. If-let is used for when you don't know what the enum variant contains (ie you don't know that it's Some(3)), but you want to access it and you know it has to be of a specific variant (ie Some(n), where n is the number you want to access). If-let basically binds the inner data of the enum variant to a local variable, letting you access it through that variable, like so:
if let Some(n) = some_value {
println!("{} + 10 = {}", n, n + 10);
}
Don't tell the other Gophers I'm here.
after testing I don't see the point of "if let" because regular "if" with "==" does the same
It was a bad example. The key point is that if-let lets you bind the inner value of the enum variant to a variable that's scoped to the if-let block, letting you safely access that inner value within the if-let block, since you've already checked that the variant is correct.
why do you call an attribute a variant?
Little bit too fast to follow, at least for me. Else very good, THX!!
Nice VIdeo
Не зрозуміло чому в останньому прикладі замість порівняння == стоїть знак присвоєння =
Bruh this is literally just the book lmao. I was hoping for something more in depth. It’s a shame there’s so little video content for rust
Yep. It’s almost word-for-word and example-for-example. I will admit, however, getting fed the chapter in 12.5 minutes is a lot faster than reading it myself. But that’s just for seeing the syntax. The diagrams showing the flow of data within memory is (imo) extremely important for understanding HOW rust works, which you don’t get in videos like these.
I'm still so confused by enums existing as a concept... I mean it's just a "legal" hardcode. Hardcode = bad code, enums != bad code. I don't get it, please someone explain this. I'm 1,5 in programing(C, JS, Python), almost a year of commertial expirience, and I've never used an enums. Literally. Why they are so functional in Rust? It really doesn't make any sence to me
What do you mean by hardcode? The awesome thing with Rust enums is that they're _not_ hard coded, they can accept and store variable values that originate from runtime code, in a way that lets you determine _what_ group of values the enum is currently storing. It's as if you took a union in C, added a tag that told you what variant the union is currently in, then sculpted the language around using that tag to make certain guarantees around the variant that the union is in when it's used in different contexts (pattern matching, if-let destructuring, let-else destructuring, etc). Take any usecase for a C union, add a ton of extra safety features on top that made it safer to use, then imagine the new usecases that would open up if you had that extra safety, and that's why they're so functional in Rust.
hahhaha... I am a go developer... turned by some like... hahahha
"The error states that we're missing an arm".
гуд )
класное худи))
he's just reciting the book, without really explaining it in his own words.
fn main() {
let some_value: Option = Some(3);
match some_value {
Some(3) => println!("This is three"),
None => println!("Nothing in there"),
_ => (),
}
if some_value == Some(3) {
println!("This is three");
}
}
(notice the capitalization)
I thought it was emus instead of enums hahahah
I think you are going too fast
5:10
Rust demonstrates how match expressions should be implemented. Switch expressions in JS are just awful...
Each sub converts a go dev to a rust dev? Let me just write a bot real quick...
Is there any Russian speaking rust community?
bro just literally took code samples from rust-lang and put it in video :(
Yeah. Why do you think those samples are there? Art-pieces? They are good examples of code in use.
Bro is hating Go
nice tut, but don't trash go man, they both good langs for different use case
This felt overly complicated for no reason
"make sure you subscribe, because every time you subscribe we convert a go developer"🤣 if I unsubscribe, a RUST developer is converted to go?
I enjoyed the content but I am not a convert just yet. You're GOing to have too do better than that ;)