Rust Tutorial Full Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
well hello internet and welcome to my rust video tutorial in this one tutorial you're basically going to get a 500 page book crammed all into one video in the description is a link to all the code along with the cheat sheets all on github and basically the reason we're going to use rust and why rust is important is it provides a high performance that is similar to c plus and is a systems programming language that is excellent at reducing memory related errors and by systems programming what i'm referring to are low level details like hardware and memory on top of that garbage collection is not necessary memory errors as we know often lead to security breaches which makes rust very attractive rust programs also tend to require much less memory in comparison to other languages and on top of that rust also excels when it comes to concurrent programming at compile time many possible concurrent programming problems are pointed out and the rust compiler is so robust that it normally finds errors not found by other language compilers and on top of that these error messages are normally very easy to understand now if you want the installation that's at the end of the video otherwise i'm going to jump directly into writing some code now i'm going to be doing this on windows but all of the commands are exactly the same on every operating system so what you're going to do is you're going to go to the directory where you want to create your rust project and you're just simply going to come in and type in cargo new and i'm going to call this rust tutorial right like that and basically cargo is the rust package manager and build system and you can use it to download libraries and build them and do countless other different things which we will cover as we continue so just type that in and there it's created and you can see here is our rust tutorial so i'm just going to change over into my rust tutorial directory and we can investigate what exactly is going on inside of here now basically whenever we run this command we're going to generate a git repository a source directory and a tamil file which stands for tom's obvious minimal language for people that care and it is basically a cargo configuration file i'll show it to you here in a second here we have visual studio code and you can see our rust tutorial here i'm going to go into source and also explaining a little bit about what is going on here here you can see the toml file that i referred to earlier and it's basically just a configuration file and it contains information on configuring the package along with dependencies which we'll get into later on cargo lock which is right here is going to store the versions for all of your dependencies and anytime you would ever want to update all of your dependencies you can just go into the command line and type in cargo update and there's a bunch of other different cargo commands that i'll get into later but let's just jump into main rs so you can see here is our hello world program now the very first thing i'm going to do is this is only for the tutorial i normally do not do this but in this circumstance if i want to get rid of warnings that talk about unused variables i can just come in here and go dollar sign and exclamation mark and then allow unused and that will get rid of some errors whenever i have variables that are not are declared but not being used so that's the only reason i'm putting that in there now there are a ton of different libraries that we're going to be able to work with i'm going to go and just install a couple of them here i'm going to say that i want to use our standard input and output library so that is just standard and i o and i'm also going to want to another thing just to cover everything if you would want to bring in all public items under this library into your specific scope you could just come in here and put a star after that but i'm not going to do that in this circumstance another thing i'm going to need is the ability to generate random values you can just type in rand and range now as you add this you're going to notice there's an error message that pops up and that's no big deal what you're going to do is just go into your toml file right here and underneath of dependencies you're just going to put in rand and this is a reference to the current version number and you're going to save that and then what you can do is if you ever want to find out what the version number is for these are called crates which are just bundles of code you can just go to dot io and type in whatever different crate you're looking to use and as you can see right there it gives you the version number another thing you can do with these libraries is you can come in here and you can actually use nested paths if you want to import many of them at once so i'm going to go standard io and then i'm going to say that i want right this is going to be used later in the tutorial to be able to work with files so we're going to say we want the buffered reader and we buffered read and error kind i'll get into exactly what all of these are later on whenever i get into working with files and i'm also going to say use standard just mixing things up here just to give you a good understanding of how we can import all of these different libraries okay and also i'm going to use something else called ordering which again i'll cover later on and this is going to be used with something called match which i'll also be covering later on all right so we have everything here and we have our main function and if you do not see run up here where this is actually going to allow us to run our application it's going to go and compile everything for us you can see hello world shows up down there i'm also going to move this over to the right side so move panel right and there we go and i think that's going to work out a little bit better for being able to see exactly what's going on all right and let's just go and collapse this all together all right so here we are and here is the ability to run your application just click on run and it runs and if you don't see that just make sure that you have the rust analyzer selected over here and it will show up under extensions it looks like little tetris pieces okay so what exactly is going on here with main well whenever we create any function we're always going to start it off with fn and whatever the name of the function is followed with parentheses and you're going to throw parameters inside of there and then you're going to have opening and curling braces that are going to define where your function both starts and ends it is very common to indent with four spaces inside of rust and print line is what we call a macro and you can tell what is a macro and what isn't if you can see the exclamation mark there then you know it is a macro and that is what it is and of course this prints out hello world onto the screen not that complicated but let's make it a little bit more complicated what i want to do here is i actually want to ask the user of our application what their name is and then address them with their name so i can do something like what is your name like this and then what i want to do is i want to be able to define what is called a mutable variable and that means it's a value that can change by default all variables you create inside of rust are immutable which means you cannot change their value but you can set them up also to have them be mutable and how you do that is you start off every declaration of a variable with let and if it's mute after this that means it's going to be a value that can change and if there's no mute that means it can't be changed and i'm just going to call this name and then i'm going to call string new and what this is is a function that's going to return an empty string and as you can see things are populated here for me as i go and write my code and this is just seeing that i want to go and create a string and it's automatically throwing in string and assigning it to the name variable so cool stuff and if you're wondering why exactly rust uses immutable variables variables whose values can't change the reason why is by using immutable variables that is going to basically eliminate having to go and track down how values change throughout your code which is going to save you a ton of time when it comes to debugging i could come in here again and i could say something like let greeting and assign it's also going to be a string and i could just say something like nice to meet you and i'll show multiple different ways of working with strings as we work through here now if you want to be able to receive input from the user you're going to use readline for that and to use it we're going to say i o and standard in we're going to be reading information from the keyboard and read line and i'll mark here that i'm going to be using a mutable parameter and i'm going to say that its value is name or its name is name and then what we're going to do is we're going to type in expect and didn't receive input and that light look a little bit weird but basically the read line function is going to receive name and the and right here the and symbol that i have highlighted right before mute is going to define that this variable is a reference to the variable and this is going to allow readline to save values directly to the name and once again you're going to use mute anytime you're working with a mutable variable and this part right here where it says expect and message didn't receive input well readline actually re returns what is called a result and a result is an enum an enumerated type and it's if an enumerated type is basically a type that has a fixed number of possible values and the two values that are going to be returned are either going to be okay ok capital o or error like this and all of this error handling is directly built into rust and what you're going to be able to do is you could go in and say if error is returned you can go and say that the operation failed and on top of that error is also going to tell you why the problem or why the function or what have you actually failed on top of that now we should handle this error but we'll cover that later on also so now what i'm going to do is i'm going to go and actually make this more interactive i'm just going to have this be hello and with print line and if you want to go and insert different variable values inside of print line you just use these curly braces like this and i could say something like exclamation mark no you don't need the exclamation mark i just threw that in there just to act like i'm very very excited to meet whoever this is then i'm going to type in name and i'm going to type in trim and like this and that's just going to get rid of the automatic new line that is going to be inserted at the end of name because the user hit a new line and then afterwards i'm going to say greeting is going to pop inside of there and if we save this and we click on run you're going to see over here that it's going to ask me for my name i can type in derek like that and it's going to say hello derek exclamation mark nice to meet you okay so good stuff now i want to do more of a deep dive into variables uh another specific type of variable we have is a constant and they are almost always going to have a name that is in uppercase letters to differentiate them from any other type of variable and another way you can you can go and separate big values is you can use an underscore like this which is very useful if you use it properly there you go and on top of that well it doesn't know what this is if i want to define exactly what type of data type we have here i just throw in a colon and i'm going to say that this is going to be an unsigned integer which is 32 bits what else can we do i can also let's go and create another constant and let's call this pi and we can also work i'm going to get into all the different data types but just to give you a quick overview this is how we define a float and i could say something like 3.141592 or something like that and another thing is let's say we define a variable called age and we define that it is actually a string you define strings with double quotes and characters with single quotes very important to remember that and what i want to do here is i'm going to create another mutable and it is also going to be called age but it is going to be an unsigned 32-bit integer right like this and what you're going to be able to do in rust is you can define variables with the same name but with different data types and this is called a shadowing and it's perfectly legal to do and so let's go in here let's say i want to go and convert the string into this unsigned integer i could say age and trim which is going to get rid of any white space and then i can call parse on it like that again i'm going to handle any errors here by saying expect and then we can say age wasn't assigned a number and you can see you're building in all of your error handling directly as you code which is ridiculously awesome i can then come in and because this is mutable i can change the age like this and then we can call print line on this and we could say something like i'm whatever and i want and let's say that we want to throw in our money inside of here so our big constant value that we have inside of there and then i can follow this up with just age and one mill and there we go and then we can of course run this and you're gonna see that it goes over and it prints all exactly what we expect but it doesn't have the underscores inside of there and that brings me into more specifics on data types now rust is statically typed which means all the types must be defined and these types are going to be auto generated very often for you by the compiler as you have seen or you can go in and define them explicitly in certain situations in which that would be useful first off we're going to talk about integers and you can see here are the different unsigned integers that we have as well as the signed integers and how you define those and you size is going to depend on your computer so if you have a 64-bit computer then it is going to be a 64-bit so let's go get rid of that one thing that's very useful is to know the maximums on all these different guys and if i want to get the maximum let's just say rather than defining a variable i'm just going to say print line just to save time and i am going to say max u 32 which is on side integer and like this and i can go and get our max value just by going unsigned integer 32-bit and max like that and i can do this for all of the different data types but i'm just going to do it for a couple so let's copy this paste that there let's do something like 64. and you just change this to 64. and let's do the use size also so let's go copy and paste that there and let's say this is you size and size like that um you can also u28 uh well let's show it here so that you can see it so let's paste this down inside of there and u128 and u128 and let's also look at our floats so we'll do something like max and f32 and f32 over here and also let's just go and copy that as well and we'll do u64 and then that's it that's all minute two you can go in there and do as many as you'd like afterwards if you'd like and then i'll get into the specifics of the precision on these different data types so because that is also very important you know as you can see these are very very large large numbers okay and you can also see how the precision works on these values okay so important stuff all right what do we want to do another variable type or data type that we are able to work with here is what are called booleans which i'm sure you're probably well aware of and we just define this with boolean and we can say something like is true is equal to true and one thing to remember is let's say that you have an unknown up here i'm not showing errors when i have unused variables but let's say you have a variable you just want to use as a placeholder and it's not currently being used and you want the rust compiler to ignore it you can just start it with an underscore and the rust compiler won't throw any types of errors and the possible values for bull is true lowercase t and false also which i'm guessing that you probably already know another one is if you wanted to create a character you could come in and just say let and my grade and remember with strings you're going to use double quotes with characters you're going to use single quotes so that is going to create a character and you can see it's automatically populated and math is pretty simple to work with i want to talk about the precision of the different floating point numbers so i'm going to create a i'll just call this num1 and i'm going to define that this is going to be 32-bit float is equal to and i'm going to go and put one point and i'm going to do 15 once all right and then what we can do is i can call print line and i can i'm going to type f32 like this and then throw our value inside of there like that and of course you're going to want to put quotes around all of this stuff so i accidentally put two curly brackets not good let's get rid of those and instead let's throw quotes inside of there and then after this i'm going to go and actually add those values together so i'm going to say num 1 plus and then i'm going to go and get 15 digits again so that we can see how precise this is so i'm just going to change this to 0 points and then i'm going to go and put 15 digits in there after that and there we are and there we are and let's just go and do the same for 64-bit so that we can see all of it at the same time on the screen so throw that like this and change this to num2 and change this to 64 and leave that all the same and change this to 64 like that and change this to num2 and if we run it you're going to see the accuracy we have here a 32-bit float is going to have six digits of precision while a 64-bit is going to have 14 digits of precision let's go and create some more let's look at a couple more at math operators of course there's a bazillion of them i'm just going to cover some of the basic things that you're going to use all the time so let's say we have we have a number 5 and we have another one and this is going to have a value of four so let's just throw four inside of there and i'll show you the basic math operators right at this moment we're going to let's say we wanted to say something like five plus four is equal to and they're like this and then we can just go and make this calculation directly inside of print line so we say num 3 plus num and we can of course do this with all of the basic types of operators that you would use in mathematics so i'll throw in minus everything's the same there we go and then for this last one this is actually going to give us the remainder so throw a remainder inside of there and if we run it you're going to see all the different math operators and exactly how they're going to work another thing to be aware of is if if this was mutable so let's change it to mutable if we wanted to be able to add one to this value we could just come in here and just say num3 and instead of saying equal to num3 plus one we could say plus equal to one like that and we would be able to do this with all the different operators of course you would just replace that addition sign i think it's interesting to do is to generate random values so let's get rid of all this and i'm going to say let random num equal to rand and you're going to call thread range and then you're going to call generate range and you're going to say that you want all values between 1 and 100 and this is how you designate a range you hit 1 dot dot and if you want 100 you're gonna have to put 101 because it goes up to 101 but it doesn't include it with our results and then we can come in and simply type something like random and we can get this value so we'll say random number and of course if we run it it's just going to generate a random value there it gave me 69. if i run it again it's going to give me 20. all right so good stuff so it's a couple little math operators and now i want to talk about if expressions a couple different ways to handle conditionals inside of rust i'm going to say let's say we want to have something called age and what i want to do here is i want to decide if a birthday is important or not so i'm going to say that anybody under the age of 18 is going to have an important birthday 21 50 and then anyone over the age of 65. we're going to say those are all important birthdays and then anything else we're going to say isn't important sorry if you're not having an important birthday so all you can do is you just say if and age is greater than or equal to and you can use multiple different conditionals with and like that so i'm going to say and age is less than or equal to 18. again curly bracket brackets gonna define all the code that executes if the these conditionals are true so i'm gonna say print line and then i'm gonna say hey you have an important birthday and there we go and then if you want to continue with this we can do an additional conditional we can say else if and we're going to say age is equal to 21 and you could also do a situation where if either of these are true with the or conditional or the or logical operator say age equal to 50 all right those are other birthdays that are important so we're going to come in here and copy this and paste it inside of there and what else did we say well we said if the age is over 65 or equal to so we're going to say age is greater than or equal to 65 well guess what you also have an important birthday and then the default of course is going to be else and in this situation your birthday is not important so i say not an important birthday and if we run that you're going to see the age is 8 and it's going to say yes 8 is an important birthday another thing this is sort of a kind of a ternary operator i'm going to cover it just because i'm trying to cover everything so if you wanted to simulate what it's like to have a ternary operator we could say something like let and immutable and my age is equal to 47 i could do something like let can vote equal to if my age is greater than or equal to 18 and then inside of here i could return true and another thing is you do not need the semicolon after this is this if this is just simply going to return a value so that's useful if there was multiple different statements only the last statement could uh exclude the semicolon and otherwise this is going to return false and then what you do is at the bottom here you just throw a semicolon in and then we can come in and we can say print line and we can say can vote and then we could decide if we can vote or not and you can throw this directly inside of your print statement as well as long as you put the right name inside of there and there we are and if we run it you're going to see that yes indeed it is true that this person can vote because they are the age of 47. another conditional that is extremely important and useful is called match and basically match is going to run different code depending upon conditions like if you're going to use match in other situations though for sort of error handling and such and so let's go and create one so i'm going to say let age 2 be equal to 8 and what i want to do is i'm basically going to copy the important birthday thing but i'm going to use match instead so i'm going to say match age 2 and then inside of here i can also throw all sorts of conditionals so i'm going to say let's say that i want a range from 1 to 18 including 18 i just go and create a range like that and if i want to also include 18 i put equals 18. you're going to follow that up with this little arrow here and then did i save the yeah look at that i saved it and the only thing is you're going to put a comma at the end here instead so that's going to match everything between the age of 1 and 18 and i can do the or statement as well so i say 21 or 50. again there we are just make sure you get rid of that semicolon and replace it with a comma i could also go and get 65 but you might say to yourself well what's the max number well you could throw something like 200 inside of there or something something that nobody would ever reach but it remember we talked about this earlier if you wanted to get the maximum um this had actually been unsigned in but whatever same difference uh you can throw that inside of there and then that's going to get everything greater than 65 and then by default you can do an underscore whoops accidentally hit the wrong key an underscore is going to match everything else it's very important when you're using match you have to be able to use every single possible value for age whenever you're defining all of these different conditionals again helps you avoid errors and here we can say not an important birthday and again leave a comment there at the end and then a semicolon at the end of this match statement and if we run it you're going to see that the age of 8 is an important birthday all right another thing i'm going to cover more with match because there's a lot going on here so let's go get rid of that and i'm going to say that i want to define my age as equal to 18 and see it's giving me errors good stuff i'm going to say let my age and i'm going to say that i want it to be equal to like that automatically populates the data type and i'm going to say let voting age be equal to 18. now what i can do is go and get match and i'm going to say my age and i'm going to use the compare function here there's all kinds of functions built into match and let's say that i want to get a reference to the voting age i can do that and throw this right here and it's giving me an error because i haven't filled in all the different parts that are needed and this is where ordering comes from see whenever i imported that library this is where i'm using it so i'm going to say ordering and i can say whoops i think i hit it twice or maybe not okay so i'm going to say ordering and less than that's what that's going to be equal to in that circumstance i'm going to say let's throw this here and then let's just change this to can't vote so can't vote and remember commas not semicolons and then we can this is basically exactly the same sometimes we'll just copy it throw this inside of there i'm going to say greater than so greater like that and it's comparing my age to the voting age that i defined here and here in this circumstance i can vote so change that to can vote and in the situation in which these are going to be equal like that i can say give like a special message here say something like you gained the right to vote because they're 18 or whatever all right and then end this with a semicolon like that and run it and you can see you gained the right to vote because i had this set for 18. all right so there's a little bit with match we're going to be covering more later on but now i want to talk about arrays now it's important an array just contains multiple different values and elements this is very important elements in an array must be of the same type data type and on top of that arrays have fixed size so let's go and create an array and i'll just call this array 1 is equal to and how you define them is you just put the square brackets and 1 2 3 and 4 look like great numbers so i'll do that let's say that you want to print the very first value inside of an array we can do that so let's call this something like first and then we can go and refer to our array that we created so array one and the first index is always going to be zero if you wanted to get the actual length of your array let's just copy this because i'm lazy let's go and type in length so length like this and to get this you just say array and get rid of this part right here and replace it with the link function and let's say we would want to go in and loop through these different variables let's create another array so i'm going to say actually let's go and just run this so let's just go run and you can see first is 1 and length is equal to 4. let's go and create another array in this circumstance so you can see if i update this so i can go and put like a whole bunch more numbers so i can say five six seven eight and nine inside of there boom see it automatically updated it from four to nine so that was useful and just to differentiate this let's call this array two and i'll get rid of this also so if you wanna loop through an array what we can do is you're going to have an index there's multiple different ways to loop i'm going to show you all of them i'm going to start off with sort of a weird one so this is a loop index it's going to change from 0 all the way up through the end of the indexes so i'm going to say that i want this to be mutable because i need to change the value there's no way i can do that otherwise and it's going to start out the very first index and we're going to say loop and what i want to do here is i want to loop through all of these different values and i want to only print the odd values inside of it so i'm going to say loop and i'm going to have to use if for this i'm going to say if array 2 and i'm going to get my loop index value and i'm going to say the or i'm going to get the remainder for this modulus 2 is equal to 0 well in that circumstance we know that we're dealing with an even value and so what i want to do is i'm going to go and get the next value after that so i'm going to say that i want to increment this value like that and then i want to jump back to the beginning of our loop and that is what continue does continues in countless numbers of programming languages so you're probably well aware of it another condition is i'm going to say array 2 and let's say that for some reason we don't want to continue past 9 or something like that so we'll throw this inside of here even though it's in the array we just want to ignore it so we're going to say equal to 9 well in that circumstance what i'm going to do is i'm going to break out of the loop all together what that's going to do is it's going to start executing code down here so no more looping we're done break the loop we're out okay so after we do this in the circumstance in which we want to print out our e or our odd values i'm just going to say val like this and then i'm going to go and get that value so i'm going to say array 2 and loop index and print it out and of course don't forget to increment your index value otherwise you'll have problems clearly and if we run it you're going to see that it's going to go in print one three five and seven it didn't print nine because we broke out of the loop whenever that happened all right so there you go that's some stuff you can do looping wise with arrays you can also use for loops so i'm just going to get rid of this guy right here and delete it and i am going to loop index is equal to zero let's just leave it the way that it is there and i'm going to say wow loop index is less than and i'm going to get my array number two loop index and there we go so i'm gonna did i forget to put that there or actually no it's going to be array 2 dot length confused for a second all right so there's the length we're going to cycle through as long as as there are values to cycle through and i'm going to say print line and then we can say array and we can print the values out just like we did before and of course we could throw a conditional in here that would break out whenever we hit nine if we would want to do that uh i'll leave it up to you to play around with those different ideas so array two and loop index and and that and then of course we're going to have to increment the loop index gratefully i save that and we can run it and you can see we're also able to cycle through values that way of course it doesn't end because we also have the ability to use for loops so for val in array number two and in this circumstance we need to create an iterator that is just simply going to provide us with the ability to cycle through all of those different items or iterate through them however you'd like to say that and we could say print line and just go and output these values as well and it's going to give us the same thing that we had with our while loop and i leave it to you to decide when you should use while loops and when you should use for loops and when you should use other looping structures and there you go we printed that as out as well and now we move on to tuples now tuples can contain multiple data types in a list of a fixed size and so let's go and create one so i'm just going to call this my tuple and you need to define what data types you're going to store inside of it let's just say unsigned 8-bit and string and a 64-bit float and then we can come in and assign some values so we'll say 47 and we're going to do more about strings like right after this but let's go in and i'm going to convert this to a string with two string so i'm going to say two string like that and then finally i'm going to say 50 000. and there we are and there we go okay so that's how we can create a tuple and as the tutorial continues i'll do a lot more little side projects with tuples as we get into sort of doing little mini type of examples but let's say we want to come in here and get our name from our tuple we can just go and say my tuple and just reference the index just like we did previously and also you can assign values to multiple different tuples at the same time so let's say we wanted to go and get these and put them into separate variables so v2 and v3 is equal to my tuple and then once again we could go and print out one of these by referencing the index value so just like this and then maybe we want to get age this time and we can go and just call v1 all right and if we run it of course it is going to output my name here and my age all right and i just mentioned string so why don't we talk about strings now basically there are two types of strings you're going to have a string which is going to be a vector of bytes that can be changed and then you are going to have this reference and string type which is going to point to the string and allow for viewing of said string so let's come in here and create an empty growable string so i'm going to call this mutable st1 is equal to and we call string and we use a couple different functions here when creating strings and let's go and say we want to insert a character at the in this situation it is at the beginning of the string but actually push pushes a character to the end of the string so you can just go st1 like this and push and remember characters are going to be single quotes so we'll throw that on there and let's say we want to insert a string at the end again so just to prove that this push is putting strings at the end so we'll say push str like this and here double quotes and we'll just say something like word or something and we'll continue let's say we want to iterate through the words by splitting at any white space that we have so we could say something like for word and you don't need to declare this variable word outside of here you can just go and type this in so i'm going to say st1 dot and split and white space like thus and there we go and then i can come in and output these so i'll say print line and we'll just go and output each individual word and there we can do that what else would i like to do let's say you'd like to replace a string so i'm going to create a new string i'll go st 2 is equal to st1 dot replace and i'm going to say that i want to replace the instance of a with the word another exactly like that and we could go and print this out so just copy this just to prove that it indeed worked so we'll just change this to st2 st2 right like that and let's run this and you're gonna see that we printed a word and then we replaced a with uh the word another let's go get rid of this and do some more stuff all right what do i want to do now well let's say i want to create a string of just random different characters so we call this st3 is equal to and string and here's another way you can create a string and at the same time assign a value to it you say from like this and then i'm just going to throw like a whole bunch of random characters inside of here so x r t b whoops b h double k because i'm going to show you how to eliminate duplicates um a m c okay so there we are just created a string now if we would want to convert this to a vector we're going to cover vectors soon but uh just for now it's kind of the chicken or the egg sort of thing we're trying to figure out what to cover and i'm going to have these be a vector that is just full of a whole bunch of characters so i can say characters and then go collect and whoops and make sure we close that off we're then going to be able to sort these characters so vector sort sort of covering strings and vectors here at the same time so that's going to sort them we can also come in and let's say we want to remove any duplicates that we have and then we can cycle through this vector so i'll do character in v1 and then just print line and i can go and output each of those individual characters as we cycle through this there we are let's do some more stuff before we run it let's say we want to create a string literal go let st4 and we're going to say and str equal to and we'll just have this be random string and let's say we want to convert to a heap allocated string we could say let and mute i get more into heaps as we continue also later on and we'll do string is equal to st 4 dot 2 string so that's how we can convert back and forth to the different types of strings and let's call print line again whoops print whoops print line let's output this and i'll just come in here like that and go st5 um anything else i'd like to do oh let's say i'd like to convert a string into an array of bytes you can do that as well just call this byte array 1 equal to st5 and then you call as bytes clearly we use strings a lot so i'm covering a lot more with them we could also get a slice of a string so let's go and let's say this is st6 is equal to and you have the am sign here st5 and let's say we want to get everything from index 0 through 5. we would go 0.6 we do not include the 6 whenever we grab this piece and let's do a couple more let's say we want to print line and i want to get this string length i don't think i covered this if i did whatever i'll try it again and length like that and let's go and grab it so we'll do st6 and length actually i think i did do this yeah whatever there shouldn't be much duplicate and then finally if we want to delete values in a string if mutable we're going to say st5 dot clear we'll do that and anything else i'd like to do let's just run this and you can see all this output so there all are different strings you can also see the duplications going it's also been stored and you can see the string length and so forth and so on uh what else would i like to do um so we did clear let's say we want to combine strings so i'm going to say st6 is equal to and i'm going to populate this with text so i'm going to call this just sum and then we're going to create another string so let's just copy that and paste it down inside of here so we'll go st 7 and we'll say words and uh what else do we want to do here spell words right and what else um okay well let's combine them so let's say let and we'll create st eight equal to st6 plus and we'll go and and this is going to get a reference to that string with the string seven but not with string six and what this means is the string six is no longer available so if we try to go and call it it doesn't exist it is in string eight now however string seven still does exist because we use the and sign here to get a reference to it to get those those values let's say we want to cycle through the letters in a string and print them out as unicode let's go character in and like i said inside the for loop you don't need to declare anything all that is handled for you so we can say bytes and let's just do another print line and i'll put this whoops quotes and there we are and we'll just output our individual character and there we go and we can run this guy right here and you can see there our unicode characters and so forth and so on all right so rundown of strings like i said as the tutorial continues we will do more with strings once we get into more complicated topics but i think that's a good overview of a lot of what you can do i like to also talk now about casting now you're gonna be able to convert uh to two to different types in a whole bunch of different ways as we've already sort of touched on i talked about strings and vectors just a second ago this is casting is going to be one of those things that is sort of covered as the tutorials continue and continue on and of course you can get the code and it's on github for free so grab it and use it as a cheat sheet and it should be really useful okay so there we go got that now let's say we want to cast one other additional way we can cast is through the as keyword so we could say something like let int 3 and we'll make this underscore 32. yeah these are weird variable names i'm sort of the difference between doing this with for a tutorial versus you know code you would use in real life so i'm going to say in u8 as and if we want this to be a 32-bit we just do that and there we are and then we're going to do the same thing for the other part and you'll be able to add those values together as you cast them so this is uh into u8 like that and there you go an additional way to cast those different guys all right all right so that's casting with as another thing i'd like to talk about is enums or enumerated types and basically they just allow you to create custom data types that have a limited number of potential values so let's say we wanted to go and have our days of the week inside of here so we could say all right so there you go there's our enumerated type for all the different days of the week something that's interesting about this is you can actually define functions for these enumerated types just go like this and reference the enumerated type you want to work with and then just throw a bunch of functions in there so one function i could use is something like if we wanted to check if a specific day is a weekend we can reference this type itself by passing self inside of it and then what do we return you're going to get more about this when we talk about functions whenever we create a function starts with fn then you have the function name then you have all the parameters passed to it then after this little arrow sign here you're going to have the return type and the return type is boolean and we'll talk about those very very soon and we're going to use our old friend match here again and you're going to notice in rust that you use match a lot more than you would use if some statements like that else's and all that so we're going to say if day is saturday or if the day is sunday well in that situation we are going to return true as a statement and then remember we have to always cover every potential value or situation where we're using match and this guy covers everything else so we'll just say if it's anything that's not saturday or sunday well then return false all right so let's then come in and actually use these guys so we'll go and we'll actually use an enum and let's call this today and reference day the enum name and then we reference the num name again but in this circumstance we pick a specific value so let's say today is monday now we can perform also different actions based on those days so we could say something like match and today and we'll just throw in all the different potential days that we have so we have monday and if it's monday what are we going to do we're going to go and print out something clever like everyone hates monday all right that's not very nice isn't it okay what else can we do well we can go in here and do this for all the different days and why not and there you go i went and put those in there for every single one of the days and they're well i don't know they're just things to say to print and what we can do now is check if a day is a specific weekend or something like that and you can play around with this code and i i think it is a spectacular idea to do so so we'll say is today the weekend and this is going to give us either true or false using our function we use and how we do that is just call today and then we can call our function directly from inside of it so we'll say is weekend like that and finish that off and what are we doing here oh i labeled this as days instead of day so just change that that's going to get rid of all the errors i believe and let's run it and you're going to see if monday is see everyone hates monday is today the weekend and that comes back as false so there you go those are enumerated types and yes we're going to do more with enumerated types later on in the video but now i want to talk about vectors all right so basically vectors are like arrays in that they can grow if mutable and one thing is they can only store values of the same type very important to remember that so let's say we wanted to create an empty vector how would we do that well we go vector and we need to define exactly what type of data we're going to store inside of it so let's say i want to have signed integers i could do this and i'm going to call vector and new right like that and let's say we want to create a vector and define values and i want to be able to grow this so i'm going to mark this as mutable and we just go back like this and then one and two and three and four and there we go uh what else would i like let's say we want to add a value to the end of our vector we can go vector two and push and throw 5 on there let's say we want to get the value from a specific index we could say like let's say we want to get it from our first vector this and then go and reference our vector 2 and 0 like that we can also go and verify values exist very important very good idea to do so so i'm going to say seconds and and i 32 equal to and vector 2 1 like this and i'm going to say match vector 2 dot get 1 and with this what we're going to do today is if we have a value here then in that situation well we know we can get the second value all right so important and if you don't like errors so we'll say second and like that and second and again we whoops that is a comma comma there we go and then if we get none as a response we can handle that and just simply come in and say no second value okay so no second value uh what else can we do oops comma again what am i doing all right comma all right so uh also we can cycle and we can also change values because this is marked as mutable so let's say we want to cycle through and we want to multiply every value in our vector times 2. so i can say 4 i in and mutable vector 2 and this gets a reference of course and we can go star i if we want to be able to manipulate these values equal to 2 and then we can cycle through set vector again so we'll say and vector 2 and we'll just print this out to verify that we actually got what we expected so we'll throw this here and there and i and what else well we'd like to be able to get the length of a vector so we'll say print line and vector length vector length and we'll throw that there and then to get our vector length you're going to notice that the variable names are the same for collections and for in many situations if you do the same type of thing rust was intelligently put together so that it uses the same types of names and let's say we want to remove the last value we can also go pop like this and in this circumstance we're going to just call for that specific value that we popped off and i'll say vector2 dot pop like that and like that and like that and all of that code and let's run it and you can see that we got all of our information that we were expecting so pretty cool stuff all right so now it's time to talk about functions now you can actually define your functions before or after main but in this circumstance i'm going to define them before and you just start them off with fn we've done a little bit with functions and i'm going to cover the most important concepts with functions now and then later on in the tutorial i'll cover generics and generics with functions whenever that makes more sense so we can just come in here and do something like hello like that and it's just going to execute exactly what the code is inside of our function whenever we run this all right it's going to say hello there you are that's it all right so let's make something a little bit more complicated let's say that we would like to be able to pass arguments to a function so we're going to say function and i'm going to call this git sum like that and then i'm going to say x now we're going to have to define exactly what this is i'm going to say that i want this to be a signed integer 32 bits and i'm going to do the same for the next so like that and then curly brackets and then we can come in and do something like print line and do something a little bit more complicated not much and equal to and then get those values that were passed to us like this and then at the same time directly inside of here go and make said calculation and we can come in and change this to get some and then inside of here say five and four something like that and run it and you're gonna see that it was able to make that calculation okay so let's get a little bit more complicated let's say we want to return a value so let's call this git sum to and everything else here is the same what we're going to need to do however is since we are returning a value we need to say the data type for the value that we are indeed returning and here what we're going to do is we're just going to type in x plus y and this is going to be the expression that's returned and if you use the semicolon you'd actually get an error because a statement doesn't evaluate to a function so you're just going to leave it exactly like this and we can just come in and say print and then after that you can just put the value inside of here we don't need to do anything fancy so just do this and like that and get rid of this extra guy and throw a quote inside of there and get some two like this and five and four and don't forget the parentheses there at the end and run it and you're going to get an answer of 9 because we passed in 5 and 4. all right um you can also use return if you'd like to do that so let's just for consistency reasons we'll just leave this like this and we could say return and this would return our value for us as well so get some three and run it and you can see that it also gives us nine you're also going to be able to return multiple different values so maybe we just want to call this get to and it's just going to get past one value and it is going to return two values well how do you do that well you're going to have to define the data type for the two values that you return and that's it basically all right and then we're just going to say return and let's say that we want to return 1 plus the value passed and 2 plus the value passed just go x plus 1 and x plus 2 and then we'll just come in and how are we going to use this maybe down inside of here we can just come in and get rid of this and remember how we receive two values well we just put them inside of parentheses and we'll call this value 1 and we'll call this value 2 and this is going to be equal to and call get 2 like that and pass 3 inside of it and then we could go and print out these different statements so let's maybe we just say nums and get both of those values and print them to the screen and this will just be value one of course and value 2. and there we are and run it and you can see that we got both of our values all right so that's how we get multiple values passed maybe down inside here also we would like to be able to define a number list and pass a list to a function and then have that list of values be summed so i'm just going to call this number list even though it's a vector but that's fine and vector like that and then we'll throw in one two three four and five and then we're going to call our function right here and actually if you want to pass a function what we can do we just call this sum list but just so i don't get derailed here let's say we have some list here and we want to pass a vector to it how we do that is we're going to say this is going to cause an error but that's okay we're going to say sum of list is equal to and our function whenever we create it's going to return one value and we can call some list which is what we're going to be passing and then and and number list and you pass a reference to the location for our number list but how do we receive it up inside of here well up inside here let's just get rid of some of this stuff what we're going to be doing is returning one single value so let's just get rid of that and this is going to be i 32 like that and inside of here to be able to receive our list we're going to call this list and then we're just going to say and reference and it's going to be a vector that is going to be uh a reference to a vector all right and we want to sum all these different values inside of here let's get rid of this also and we're going to say let and we're going to have a mutable and i'll call this sum equal to zero and then i'm going to cycle through how we cycle through these list items covered this already but it's good of course to cover it again list and we need an iterator that is going to be able to cycle through all these different values for us and then we just say sum plus equal to and then to get the actual value we put our reference operator inside of there and then to return a value we put sum again and we do not put a semicolon unless we put return on on that but we didn't so there we are and you can see sum of list is equal to 15. and there is a rundown of a little bit on functions much more is coming so let's just get rid of this here and what we want to do now is talk about generics now basically or specifically generic types we can actually specify the data type to be used at a later time with generics and it's mainly used when we want to create functions that can work with multiple different types of data and it can be used with structs enoms traits etc we'll cover traits later on and uh so let's go and create some so up inside of here remember you can put your functions before or after main doesn't matter but one thing we're going to have to do here is we're we're going to try to add two values that we do not understand so let's come in and first let's just try to do this and then errors are going to come up and then i'm going to show you how to solve them so i'm going to put gen on there for generic and what we're going to do like if we just put t inside of here like this this is normally how you define a generic and then you say that you're going to receive two values like this and y like this and then you're going to return some other value data type that we don't know what it is and then we're just going to go return x plus y we are not going to be able to do this why are we not going to be able to do it well you cannot use this addition operator here on generics in the form that we are working with so what we're going to do is we're going to talk more about traits later on but basically what this is this is called an ad trait and what it does is it specifies the functionality of the addition operator for different data types so we need to go use standard ops and then add like this and this is going to allow us to perform addition with our our generics say and but we're going to have to change some stuff so we can't just simply say t and what we do is these uh this doesn't have to be t it can be t u whatever you want it to be it's just a stand in and the compiler is going to understand this is a generic type meaning that it's literally any type and we are going to want the compiler to work through it now there's some limitations but basically this ad trait that we have right here is going to allow us to work with different types of numbers a wide range of different types of numbers and i leave it to you to go and actually search for this you can just type this in type rust and paste it inside of there and it'll show you all the different data types that it will allow you to add with if you you know type that in and so forth all right you can see the problem goes away now so now what we want to do is just go and add these values together so down inside of main we can go and say print line and we can say five plus four is equal to and then we can call our get some gen function and we can type in five and we can type in four like that all right so that allows us to work with integers but it's also going to allow us to work with floats and like i said multiple other different data types that you can look up so let's say this is 5.2 and 4.6 and you know the name stays the same obviously and we can change this to 5.2 and this to 4.6 and save it and even though the data types are completely different it's able to work with both of those different data types all right so a little bit more on generics later on but that is the basics of working with generics and this brings us to the concept of ownership now memory is going to be managed through a system of ownership with rules that are checked at compile time and to understand this you must understand the difference between two parts of memory which would be stack and the heap now you have the stack which is going to store values in a last in first out format and with the stack data on the stack must have a defined size then you're going to have what is called the heap now whenever you're putting data on the heap you request a certain amount of space and the operating system then is going to find space that is available and then it's going to return an address for that space and that reference to the space in memory is going to be called a pointer it's like an address now there's a couple rules you have to be aware of each value is going to have a variable that's called its owner there's only one owner at any one time and whenever the owner goes out of scope the value is going to disappear so basically whenever the compiler says okay we're no longer going to be using this then it just is deleted and that memory is free now one thing to be aware of is while automatic deallocation of resource is great there are problems that can occur so imagine for example if you copied a string if you do the string just stores a pointer to the first index and the memory required for each character and then the number of characters that you would have now what happens if for example we would we would delete one of those drinks well that information would then be deallocated for both strings now this is whenever we would copy and uh you just have to understand the concept that rust is going to free resources by default in most circumstances but what's great is the compiler is super awesome and it's going to alert you to potential problems almost always so that's a great thing so for example let's give you an example here versus just talking so let's say we have let and string one is equal to and string from and we're going to assign a word to this being world then we're going to go let string 2 be equal to whoops mess that up strength 2 is equal to str 1 like that now we just copied that over that means it doesn't exist anymore so for example if you would come in here and try to print this out so you'd say something like hello like that and str1 like that you're going to see an error what's it say borrow of moved value string 1. basically what that means is you took the value that was originally signed here and assigned it here and this does no longer exist all right so you will that's would cause a lot of problems however let's say we would come in and we would instead say that string two is going to be cloned so we'll just change this string two is going to be str one dot clone and what this is going to do is it's actually going to make two copies in this circumstance and whenever we do this you can see the error actually goes away and if we run it you can actually see that it's going to print so it's just the difference between using the assignment operator and using the clone operator and understanding both of those another thing that's important to understand is that this is not going to apply with data types such as integers booleans characters floats tuples uh it will apply with strings and arrays and vectors and all that stuff let's create some functions here also to sort of demonstrate what is going on so i'm going to come up here and i'm going to create a couple functions let's go function and just print string it's going to receive a string like this and it is just simply going to print that string so we'll say uh print string and we will say a string something like that and let's go and get the value passed inside of there and print it let's do a couple of functions though so we can sort of see now we're going to go print and return whoops return string and again it's going to receive a string and it's going to return a string and like this and why don't we go and print the string and then return it so we'll go like this copy paste that in there and then also return the string remember we can just put x inside of here and that's good and then on top of that let's also come in and try to change the string so we'll say change string and we'll go name and to do so we need to say it's mutable and that it's a reference to our string and inside of there and we'll say something like name and just use a function for this we'll go push string push string like this and we will say is happy so like that there we go and what else let's go and print line and we'll print out a message here so we'll say message and the message is going to be whatever name is so there you go couple different functions that we have here now let's run them so we can just go uh what do i want to do with this let's just leave this the way that it is and let's get rid of this print statement right here and i'm going to say print string so it's just pretty straightforward print string and which one do we want to print let's try printing the first string so you can see here's print string it just receives a string and it's going to say a string and print it all right pretty straightforward and you can see that it prints a string world all right so a little bit weird but there you go and uh what else can we do well let's test out the returning of a string so i'm just going to leave this like that and then i'm going to come in and i'm going to say let string 3 equal to print and return string and we'll pass in string four again or string one again and if we run that you can see that it's going to go and print that out on the screen as well all right so good stuff and it's going to be stored inside of here so if we go and take this and we print this out whoops like this we can go and get string 3 is equal to and str3 semicolon so it's going to print out that statement and it's also going to return the value from our function and then if a function is going to borrow a reference it can't change it unless we create a mutable version of it so just remember that and another thing that's important to remember is you can only create one mutable version inside of a function so just a couple little things that we can do here so let's change this to my name let's get rid of this because we never use it anyway and it's just getting in the way so we just wanted to call for that string to be changed so we'll go change string and mark this as a reference and mutable and string one like that oh and of course we're gonna have to make this as mutable that's why it's giving me that error errors go away and run it and you can see that it didn't print it did indeed print derek is happy all right so rundown of working with strings and passing those two functions and more on those subjects in the future but of course i have to move on and what i'd like to talk about next are hash maps all right so hash maps are going to be used to store key value pairs and to use them we're going to need to come in here and get a library so we're going to say use standard collections and hashmap and hash map like this all right so now that we have that set up we can come inside of main and create some and remember all the code is available in the description it's on github so let's say we wanted to do something like some superhero stuff and we'll say hash map and to create a new hash map we just say new and then what we're going to do is we can insert different values into our hash map so we can say heroes dot insert and what should automatically populate so we're going to say superman and we are going to say clark kent like that and boom and it automatically knows these are strings see that's how great the compiler is for rust it saves you a ton of time so let's go and create a couple more and you can see there's the k and the v for key and value paste this inside of here and what we're going to do next is let's do batman or something so batman and he is bruce wayne and this so bruce wayne and for the last one we will do the flash and so the flash and we will go barry allen okay so there are our hash maps and our hash map values now you can iterate over a hash map and get our keys and values so we can just go k and v in heroes and we need our iterator to be able to iterate through them and then we're just going to go and print out both of those so we'll say this is equal to this and then we can just go k and v so it just gets the key and the value all at the same time so we run it and you can see that it does do that for us all right so let's say now that we want to get our length for our hash map how do we do that well we just go length and take a wild guess because rust is very consistent with its naming it's just heroes like that and length like that now very often we want to be very safe about what we are doing with rust and so let's say we want to check for a specific key in a hash map before we try to print out anything or something along those lines well we could say if heroes dot contains a key and it's going to be batman so we'll say batman whoops batman spelled correctly well in that circumstance we're going to say let the batman and get rid of this space let the batman equal to heroes dot get and and batman whoops like that now we can use match to verify that the batman exists so we can say the batman and we could say sum and x is whoops why did i do that let's just get rid of this all together sum x and then in that circumstance what we want to do is we want to print out batman is a hero so great line like that and batman is a hero and otherwise if anything else comes back we want to say none and we will say print line and we'll say batman is not a hero and change these two commas and boom and boom and there you go and we can run it and you can see that batman is a hero comes back all right so cool stuff rundown of hash maps and some things that you can do with hash maps and now i want to talk about structs now a struct is a custom data type that's going to store multiple different types of data so we can create a struct here and let's call it customer and define the types of things we want to be able to store about our customers so we say something like string and address which is also a string and balance maybe the amount of money that said customer owes us or something like that okay so let's go and actually create a customer so we'll say let and we want it to be mutable so we're going to mark it mute is bob and then to define this you just say customer and then you're going to say the name is going to be string from and we'll say his name is bob smith or something like that so there's that whoops and there we go and then we'll say his address is going to be string from it is 555 main street and then we'll say that bob smith owes us 234 dollars and 50 cents okay and then put the semicolon at the end and there you are you just created a customer now what would you do if you wanted to change a value well we just go and this is mutable that's why we can do this we could say string and we could say what happens if bob smith moves so we'll say that bob smith moves to 505 main street and then that's it there we are and we could print this out and you'll see bob's new address now what is interesting is you can actually accept multiple different types of data using generics just like we did with functions so let's go and let's create just delete that and let's create a struct and it is a rectangle and we'll mark it as t and u and [Music] boom like that and we'll say that we have a it's going to store length which is going to be a certain t value and height which is going to be a certain u value we can then come down inside here and say let rec equal to rectangle and then assign said values to this with x4 and wife 10.5 something along those lines except this is going to be length and this is going to be height height like this there we go so that's how we would define that another thing that we can do is we can actually tie struct properties to functions using traits remember i kept talking about traits all the time well here's our opportunity to use a trait so let's create a trait called shape and what's cool about this is these functions can be used by any structs that implement the correct trait so we're going to go trait shape and we're going to define a function inside of it so this is what we would refer to as a constructor and it's going to return a certain shape and so we'll just call this length and we'll define that it is a float and that it has a width which is also a float and it is going to return itself so there we are and that's why it's called a constructor we can also come in here and define some functions this is an area function that is going to belong to this trait and it is going to receive something that is a shape type of trait and it is going to return a float okay so what this is doing is just defining what everything is sort of like an interface in object oriented languages it's defining the things that anyone who implements our shape must do so let's go and create another rectangle here so uh struct and rectangle get rid of all that and let's put this after this so let's go cut this out of here and move that there now we can come down here and go struct rectangle and length colon f 32 and width colon f 32 and let's do something similar also for circle so we'll do this and like that and then just change this to circle and all that will just leave the same and then what we can do is implement the trait for rectangle so we'll go implement shape for rectangle like this and we're going to have a constructor here so we'll say mu and length and this is f32 and width is f32 and it is going to return a rectangle and then we can come down here and say return rectangle with a length and spell length right and width likewise it's giving me an error because i didn't go and also create array or area i mean so now we're going to say area self is going to of course allow us to refer to parameters that for this specific struct so we're going to pass self into it and this is going to return a float just as defined and in this circumstance we'll say return self and length times so the rectangle's length and the rectangle's width and you can see that that all gets passed back but this needs to be capitalized exactly like that now we can implement the trait again for circle and we're basically going to do exactly the same thing so let's just copy this paste this inside of here and implement shape 4 but in this circumstance it's going to be circle instead of rectangle and a couple things need to change this needs to of course be circle so it's going to return circles and this is going to be circle also so there's circle and length and width and then down here inside of area of course this isn't quite going to work what we're going to need to do is change this to a circle area and so we'll divide by 2.0 like that and then just get rid of this that and go the power function for floats so 2.0 and then we are going to multiply that times our pi value that we created earlier so this is a constant let's go up here and put it inside of this guy right here so we'll go constant high f 32 is equal to 3.141592 like that and there is our pi value and now what's cool is we can actually refer to these as if they are shapes so we created both of those and we can go let and let's just call this wreck rectangle is equal to shape and new and we'll say that this is just 10 and 10 just to keep this very very simple like that and we'll do the same for our circle so change this to circle of course and change this to cirque or something so there's cirque and shape new and everything else is exactly the same and now what we can do is we can come in and create our area for this so we'll get rectangle area and that is going to be this and we will say rectangle area like that and that is going to give our rectangle area and then we'll do exactly the same thing for our circle area so circ area and just change this to circ like that and we can go and run it and boom you can see we get our correct answers all right so cool stuff there's some messing around with and also you're going to be able to use generics and such go ahead on your own and play around with throwing in generics just like we did before that would be fantastic or fantastic practice and up next what i want to do is talk about packages crates and modules all right so of course it's very important to keep all of your code organized and of course what i'm doing here where i have you know a main function full of stuff is not normally how you program now you can split your code into multiple files and packages can actually contain multiple crates which is just files with code in it and you can define what code is public as well as what code is private now what i want to do here is i actually want to go and create a new folder inside of the source directory so i'm going to go up inside of here and click on that and i'm going to use what is considered to be a common way of introducing new people to these type of modules and crates and so forth i'm going to use a restaurant example and basically it's going to break the code across multiple different files and allow you to just simulate working in a restaurant now what's important to know is that crates are modules that produce a library or an executable modules are going to organize and handle privacy packages build tests and share crates and paths provide a way for us for naming items such as structs and functions but i'm gonna inside of our restaurant folder we just created here i'm gonna create a new file and this file also will be available on github and i'm going to name this mod dot rs there that is and here is our module that we're going to create now something that's important to know is packages can contain zero or one library crates and they can also create as many binary crates as you would want and if you want to create binary crates what you would do is create a bin folder and save those but i'm not really going to get into that i'm going to sort of keep this as understandable as humanly possible so this is where we're going to create our module and it can contain other modules and it can hold functions structs enums constants traits and i'm going to show you how to reference those and it just provides a way for us to organize our code and also it allows us to make certain parts of our code private as well as public and everything is going to be private by default so we are going to create a module and i am calling this pizza order and i'm going to create a struct inside of it and it is going to be called pizza and our pizzas are going to we have to make this public so what is a pizza well it is dough which we're going to say is a string and it is also cheese most of the time and it is also going to have a certain topping so we'll go topping and we'll just say that these are some sort of default things and these are all going to be strings okay so we created a struct what do we want to do now well we want to implement functionality for this pizza struct so we'll go implement pizza and that just means we're creating functions to interact with it so i'm going to make this also public function and let's say that we're going to focus here on just um a lunch scenario of course you can have multiple different scenarios and i'll get more into that so we're going to have a topping and string be passed to this and it is going to then return a pizza so we will create our pizza inside of here and we need to define different things and we're going to do some default stuff so we're going to say our dough and we're going to mark this as a string from and we'll just say regular dough and let's move this over a little bit so that we can fit everything here on one line so regular dough and then we're going to say our cheese if i can spell cheese there we are cheese again string and from and we'll say mozzarella and then we are going to say that the topping is going to be user defined so of course we could have all these be user defined i'm just trying to keep this as simple as humanly possible and that is going to be whatever topping they passed in and put that like that and that is going to create our pizza all right so what are some other things that we'd like to do inside of this guy well we would like to be able to help the customer and then we're just gonna we're simulating a restaurant experience here okay so we're going to say that this is going to be public and we're going to make it public so that our other functions can call it and we're going to just call this help customer and all this is going to do for us is it's just going to have a function inside of it we can throw a whole bunch of functions inside of it and we'll say seat at table and whenever this is called this is just simply going to say print line and [Music] customer seated at table boop table there we are okay so fairly simple and what else are we going to do with this well we're going to throw a couple other different functions inside of here maybe we want to be able to take the customer's order so we'll say public and oops yeah let's make this public and we'll say fn and take order and throw that there and what this is going to do is it's going to be a little bit more complicated this is going to call the seed at table function for us and it's going to seek the customer it's very important to understand that making help customer public doesn't make this child function also public so we have to make both of them public if we want to be able to make them accessible so now what we're going to do is say customer pizza and we want to call super on this so pizza equal and super is going to allow me to access pizza in the parent scope so we'll do like this so we can go to the next line and say super pizza and we are specifically looking for lunch that we are going to pass a topping of veggies to so there's that and then after we do that we're going to call serve customer and custar pizza there we are okay so simulating this whole experience by breaking everything down into functions all right so we have a serve customer here but we didn't create that function so let's create that so we'll say serve and this doesn't have to be public so anytime something doesn't have to be public of course we don't want it to be so we're going to say pizza and super and then down inside of here we can say print line and the customer is served a regular pizza with and then our specific topping and to get that you just say customer pizza like that and topping like that whoops i accidentally hit my caps lock topping and there we go now we have all this set up but we want to be able to provide a public function that is going to allow other files to come in here and sort of use these functions so to do that i'm going to go public function order food like this and then it is going to reference the other code we want to work with here to do so you go crate because these are both in our source directory so and we're going to be calling this from our main function so we go crate which is that source directory then we have to say what directory we want to access we want our access restaurant which we created and then we're going to say pizza order is what we want to oops pizza order like that and then specifically help customer like that and then we want to access take order and this is how we are able to work our way through all these different parts so restaurants the directory pizza order so we're coming up here to our module called pizza order then we're going to help customer so we're going to go to this module inside of here called help customer see we have functions inside of here we have modules inside of here we have everything we also have structs inside of here and help customer and then we go to take order which is this specific function so that's how we walk our way through actually accessing all of these different functions then over in main we can call order food and it's automatically going to access all of this stuff and that is just how simple it will be so we say order food and i think i saved that and if we run this it's going to say hey order food can't find location for this okay did i save that let's go back over here and save this jump back over here save it again and what's it saying it's saying cannot find function order food in this scope why is that all right so if we want to use these over in our main function well we need to say hey we need to use these so what we would want to do is we want to declare that we want to use the restaurant module here so you just go mod and restaurant like that and then to finally get rid of that error we need to declare a specific function we're going to be using which is going to be order food to access that so we'll say use crate and restaurant like that and order food and there we go and now the error goes away and we run it and you can see that it is going to work so we'll say customer see that table customers serve regular pizza with veggies and that is what we were looking for so there you go again play around with this and test out your own ideas to really master it and up next what we're going to do is talk about reading and writing the files and at the same time i decided to combine error handling with this so that you get a hands-on example of how error handling is useful now russ doesn't have exceptions like other languages it's going to handle recoverable errors with result which we've seen already and the panic macro for unrecoverable errors which we've also actually seen at least i think i made at least one error now basically when the panic macro executes your program prints an error and memory is cleaned up and then the program quits itself so we can just go and trigger one on ourselves on ourselves if we would like to so here's terrible error and we can just go and run it and of course it's just going to print terrible error and all kinds of other information all right but that's normally not something we would want to do so let's go and trigger a panic error here on our own so let's say we want to access an array that is you know like an index in an array that doesn't exist that's a situation in which you would have an error and i already showed you how to avoid this error previously so let's come in and just throw in something just to cause an error so we'll go little array and we'll say that we want to access index 10 and then we'll run it and you can see yes indeed that's bad and all kinds of bad stuff happens all right but what i wanted to do rather than just cover that is to show you some real world scenarios so i'm going to show you a whole bunch of different ways to handle errors and in this specific situation what we're looking to do is work with files but this will apply to just about any other type of ways of handling errors so what we want to do is we want to create a file and it's just going to be called lines of text okay so there is our file and basically what happens well let's just go and create a file and handle the errors along the way so we're going to say let out put equal and we'll call a call file create so this is going to create our file and there is the name that we have and we're going to say let mute output equal to and here is a situation in which we're handling potential errors we're going to say match output and basically what is going on here is result is going to have two variants we're either going to have okay or error and the t is going to represent the type of the value that is going to be returned in a situation in which everything is okay and in this situation the e is going to represent a specific type of error so what we're going to do is basically handle those so we're going to say ok and file in this situation we're just going to use file and otherwise we're going to get a error so we'll say error and in this situation we're going to come in and we are going to trigger panic which is going to put an error message on the screen which is going to be you know our specific file creation error so problem creating file and then we could come in here and because this is a result we want to go and put a colon and a question mark inside of here to catch this specific error that was triggered and this error is triggered because we have to put curly brackets around this so just go get the curly bracket and then come down here and after this put our closing curly bracket and that problem goes away and you have to end this with a semicolon all right so now what we want to do is we want to write to the file and define the panic error message that could be expected if there was some type of a problem with it and we're going to use expect for that so we're going to say we want to write to the file and we're going to put our output inside of here and then after this well we're going to actually write down exactly what we want written to the file and this is how we issue new lines so we're going to just random words so that's what we want to put inside of there and then after this we'll say expect and this is going to be the error that is triggered if we could not write to the file so failed to write to file right like that and there we go all right so let's continue so multiple different ways of handling errors triggering errors and so forth now let's go and let's say that we want to open a file and if everything is okay we what we want to do is we want to unwrap and return the file if there was no panic triggered so we're going to say let input equal to and file open and path this is our file name and then we'll call unwrap and that's what unwrap does unwrap basically ignores the result and just gives us the output that we want to receive from our file so that's another way of going around using the result so we're going to say buffered and we're going to call our buffered reader to read this in one line at a time and then we'll say input oops input there we are get rid of that oops input and now what we can do is cycle through and print all of those individual lines let's just keep this all on one place so down here we'll just go four line in buffered dot lines and then we'll say print line and put all of this out onto our screen so we'll say buffered like that and line dot unwrap again unwrap is going to give us the content we want instead of giving us a result and then we can come up here and we can run it and you can see just some words so we were able to write to the file and then we were also able to receive just some words from our file all right so good stuff another thing you can do is you can also catch specific errors so this is going to sort of stack so once again let's go let and output 2 equal to file and call create again and this one's just going to be called random text then i'm going to say let output 2 equal to match output 2 and then handle ok again so ok file and return file and otherwise if we have an error i'm going to go and look for specific errors this time instead of just a catch-all scenario like we were using before so here we'll say match error and kind and then look for specific times or specific types of errors so and you can look these up of course the situation will change depending on what you're looking for so let's say we have a not found error well then we can stack match and we'll say file create and we want to create our file and that's what that's going to do for us and then we can also stack additional errors here so we can say or additional matches here so we'll say okay if our file was created so we said hey we want to get this file and it said hey we don't have that file and he said okay i want to catch that file or i want to create that file and then it said okay create it and now we're going to catch any errors that would come about by trying to create a file so we'll say panic and then in this situation we could say can't create file for some unknown reason that the error message will provide for us and once again instead of getting a result in this circumstance we want to use colon and a question mark here to get our actual error printed out and there that is and down here we have to put another comma and then after that we could go and do a catch-all for any other potential errors that we might have so we can just say other error and in this situation also trigger panic and here we'll go problem opening file and again to print out the error message colon question mark like this and whatever the error was in that circumstance so you got that and then another comma here and a semicolon here there he goes and i think i got everything and we can come in and we can run this and you can see that that prints that out and there were no errors in creating anything else there you go there's a rundown of how to open and write two files and read from files and also a whole bunch of different ways of handling different types of errors and now what i want to do is i've talked about iterators but i want to briefly cover them a little bit more all right so um basically an iterator can help us cycle through values in arrays or vectors or maps and we're going to cover maps here in a second so let's go and let's create a mutable array and give it a value of one two three and four whoops you have to put this inside of square brackets one two three and four there we go and we'll create a iterator for it so we'll go array i t and iterator like that just allows us to cycle through those values and go and print out said values right like this so there we go and there we go now an iterator is going to cycle through these values by borrowing so it's not going to actually take the collection and remove it from memory it's going to borrow those values and so the collection is not moved but the one downside to this is you're not going to be able to change values if you you know use that this specific way you could also come in and go array i t like this and into iterator like this and in this situation you'll consume the collection but you'll no longer be able to use the collection so there's a positive and negative to both of them and another thing you can do is you can actually create an iterator so let's go numerator it obviously has to be mutable equal to and array i t dot iterator like that and then you can just go print line and then let's say we wanted to get our first value out of this we could actually get as many values as we would want but we're going to come in here like this again we're going to call the iterator and what you could actually do is manually call it each individual piece inside of your collection by just calling next like that and that is going to allow you to get those different values and if we run this you're going to see it prints all of them and then in in the other situation it's just going to print the very first one all right so there is just a little bit about iterators and i want to talk about something a little bit more cool which is closures now basically a closure is a function without a name and they are more than likely going to be stored in a variable and they can be used to pass a function into another function and the basic layout for creating closure is you're going to say let and you could have a variable name then this is the part that's a little different you're going to use pipe characters and inside of the pipe characters you're going to list any parameters that you have and then you are also going to have a return type and then after that inside of curly brackets you'll have your body of you know the code that actually does stuff all right so let's create a couple different closures so let's create a closure that's going to define if somebody can vote we could say something like let can vote equal to and again parameters inside of pipes i'm going to say age is going to be um a integer 32-bit integer let's close that off and then again you're inside of curly brackets you're going to do something and we're just going to say age greater than or equal to 18 and remember we do not need to use return in this situation and there you go and we could come in and then go and find out if somebody can vote so we'll say can vote like this and then can vote and we'll throw a value inside of there and it's going to give us our answer see comes back as false all right so that's a basic type of closure let's get more complicated another thing that's important to understand is closures can access variables outside of its body unlike functions whenever it is borrowing so um we can go mute and sample one sample one is equal to five and then we can say let print variable equal to and if you don't have any parameters you just leave that empty and you can say print line like that and we can say we can reach outside here and we can say sample one is going to be equal to and what is it equal to sample one and that is going to work for us as well and then we can just go and call print var like this and there we go let's do some more things let's go and do sample 1 is equal to 10 change our value and you can also change values if you mark a closure as mutable so let's go mutable change var equal to again nothing in there we'll just put that there and we can just go samp one plus or equal to what i'm doing here is i'm just showing you how these values are going to change so we'll call change var like this and continue so we can go print line and we can go and output samp1's value again [Music] with samp1 and then go samp1 is equal to 10. stuff that you can't do with a um function a normal function unless you do other sorts of things so and let's just go let's just copy this rather than typing it out again so we'll just go copy and paste this inside of here save it and run it and boom and you're gonna see the changing values for sample one so sample one is five right here we jump inside of here we print out that value and that's the print var right there we change it to ten we jump inside of here we add 1 to it then we go and say we want to print it out again and you get 11. and then we changed it to 10 outside of any of these closures and it still has the value of 10. all right so there you go some different uh proof of how you can change values using closures mess around with those different guys now another thing you can do is you can actually pass closures to functions so what we're going to do is i'm going to go function and use function you can also create i don't think i've ever done this you can actually create functions inside of your main function something you wouldn't normally do i'm just sort of showing you so this is going to be a generic and what we're going to do here is we're going to say there's two or three different variables or two variables and a function and what we're going to do is we're going to pass in one function that is going to add and another function that is going to multiply into this use function so and this isn't something that only works whenever you create a function in main you can create this outside of main i'm just doing this just uh for convenience reasons okay so we'll go like this and then if we want to pass in a function we go like this and we'll label that as a generic because we don't we want to be able to accept multiple different types and this is going to return a integer 32-bit int and then you need to say where t and you're going to have list of the style or the data types or the parameters that your functions are going to have that's something you have to do so we'll say i32 and i 32 but other than that the functions can do absolutely anything on those and it's also going to return an integer so all that is defined and then all this function is going to do is receive this function with those two values then put push those two values onto our function and the different functions going to execute when you see this work you're going to understand so create another closure it's going to be called sum it's going to receive two parameters which are going to be passed from the function use function so i'll just label these as a and b like that and then it is just simply going to add those values together like that and we can come down here grab this and paste this inside of here and this guy is just going to let's call this product instead or prod just to be a little bit abbreviate this a little bit and what it's going to do is multiply those different values together and then we can simply come in here and go print line like this and execute different ones so we'll say something like 5 plus 4 is equal to curly brackets and then we can go and pass different functions into that function and have them automatically execute so we'll say 5 4 and our closure name sum and then we will come in here and grab this and then pass in product instead so we'll do this and we'll do that and this will be our prod function instead and we can run it and you can see that it automatically went in and used the correct function with those values that we passed in all right so we're going to do a little bit more with closures later on but now what i'd like to do is talk about smart pointers all right so we're going to do some somewhat real world scenarios here when we're talking about smart pointers i'm going to talk about the box smart pointer and the reference pointer and but basically a pointer is just an address to a location in memory and we've been using them across this whole entire tutorial anytime we use this guy right here which is the reference operator to borrow a value rather than taking it and having it cleaned out of memory and we've used other smart pointers strings and vectors are also smart pointers and why is that well they they own the data and they also have functions for manipulating that data and basically smart pointers just provide functionality beyond referencing a specific location in memory which would be different than with other programming languages and on top of that as you'll see later on they can also be used to track the ownership of data okay so let's talk about box here first and what i want to do is i'm going to create what is called a binary tree data structure utilizing box so we're talking about box this is a smart pointer that specifically we're going to be looking at and basically a box smart pointer just stores data on the heap instead of the stack i talked about the difference between the heap and the stack previously if you do not remember which is definitely okay stack is going to store values in a last in first out format think of it like plates that you would stack you would stack all your plates and then if you needed a new plate you wouldn't pull the plate out from the bottom and crush all the other plates no you just take a plate off the top that's exactly how the stack works and then you have your heap and whenever you put data on the heap you're going to request a certain amount of space and then the operating system is going to find that amount of space somewhere in memory and allow you to store that information now a box is normally going to be used when you have a large amount of data that is stored on the heap and then you pass pointers to it on the stack and if you want to create a box you can just say something like let and let's go n1 is equal to box new and 10. okay and you're going to be able to access this in multiple different ways you can access it in a very straightforward way you could just come in and say b int one is equal to to get this value and just say b and one like that and like that and run it and boom there you go you got your value back but we're going to do something a little bit more complicated so um let's create a struct that's what i want to do i'm going to create a struct and i want to try to create a binary tree so i'm going to say struct and i'll just call this tree node and here is our generic remember i said we're going to do more with them i'm going to have basically a tree the way that it's structured is you're going to have like let's say you have a value of 50 underneath of it if you can picture this let's see if i can find it so you have underneath of it you're going to have two different arms like this and they're going to reference other values that are underneath of it so maybe something like 35 and 40 and then these will have additional arms and it creates a tree okay so what i want to do is try to create a a binary tree data structure inside of rust so i have a left arm and i have a right arm where i'll store these and this is going to store additional tree nodes inside of it so let's do that and then we're going to have a left and a right so let's do this and there's also the opportunity where we will um they won't have a left and a right okay so we'll have to handle that as well which we will and then on top of this let's just say that each of these keep them very simple we're going to have some type of key all right so there is our struct and this is going to have errors i know that i'm doing that on purpose to sort of point out some different things now the reason why we're going to get errors is if we try to create a binary tree we're going to get an error or actually multiple different errors one's going to be that a if we store like a string inside of here that the string can't be known at compilation time but also we're going to have other different errors here because russ doesn't like null values and like i said if we have a tree and there is no additional node or value that is attached to the left or the right for our said tree which is definitely something that's going to happen that's going to trigger other types of errors but i'm going to show you how you can use box to sort of fix that so how exactly do you fix it well we can just leave this largely unchanged and the only thing that's going to be different is instead of putting tree node inside of here we're going to say option box tree node like that and then we'll just have everything else be basically the same so we'll just come in here grab this again copy this and paste this inside of here once again and save it and now you can see everything's okay all right so it doesn't like the idea of having a tree node inside of tree nodes and so forth and so on and what happens if this tree node is um deleted and then we have all these other tree nodes that are tied to that tree node it causes all kinds of memory problems okay so we're going to handle that just by putting all of those additional tree nodes inside of boxes now what we can do is we can create some functions for creating nodes and then adding left and right nodes as well so we'll just come in here like this and this is going to be a generic and we'll call this tree node and again generic and we can go make this public so we can access it to create new tree nodes it's just going to be past a key that's the only value assigned to it and then it's going to return a tree node and we'll go self and create a tree node inside of here and we just have to define what these are going to be and it's perfectly okay in this situation to mark these as none because it's a brand new node so we don't have anything assigned to it yet so we'll just do none like that and then the key part is just going to be key so we can just get rid of all of that let's delete this and get rid of that and put this like this okay so good stuff and then what we can do is well don't throw another comma here because it's just good practice we have that all set up and everything else looks good what else can we do here well we can go and generate a opportunity for assigning a left tree node so we'll create another function inside of here so left and mute and we'll get past self and node and we get past a new tree node after we create a new tree node with the new function and then what's this going to return it's going to return self and from this point on we will say the self left is equal to sum box new node it's getting a little bit in the weeds here now when we're messing around with this stuff and then after we do that we can return self and there it is and we can also add the option of being able to add a right node to our tree so you can just change this to right something like that entry node itself just change this to right and provides us with the options of adding all of these other different nodes and i forgot to capitalize box here that's why i'm getting these weird errors so let's get this like that and the errors went away and what else would we do well i'm just going to you can go and play around with this on your own i'm in a rush here to sort of get into concurrency but basically to create a root node and then assign left and right nodes all at the same time you could just go let's just call this node one is equal to tree node and new one like that and then we could say dot left and call on this new node that we just created we can also go and assign just to show i'm just looking for reasons to show you new stuff so here is an additional way of creating the left node and then let's also create our right node and tree node and also new and three so just an interesting way to structure that to go and create those and uh you can just go ahead play around with that but now what i'd like to do is cover concurrency and what i'd like to do is use sort of a real world scenario where we simulate bank transactions now basically concurrent programming is going to involve executing different blocks of code into pla independently so we have what is commonly talked about which is parallel parallel programming and it's different in that code executes at the same time and these different blocks of code that execute are referred to as threads and basically a thread is going to handle the scheduling as well as the execution of these blocks of code now there are common problems whenever you're dealing with parallel programming for example a thread tries to access data in the wrong order that's a very common error also threads are blocked from executing because of confusion over requirements to proceed with execution so for example you have a thread that can only proceed if it has access to something and another thread has access to that thing and so it that thread will not stop execution until it passes that information for the other active thread to execute all these other different problems well rust is going to handle a lot of these issues for us so what we're going to need to do here is we're going to need to go in and get a couple more libraries so standard and thread and use i'm gonna have to work with time and so forth so i'm gonna need to go and get time and duration also and uh it's giving me an error and that's because i didn't put this extra colon inside of here all right so there we are so we got that set up we have the libraries to work with now i'm again i'm going to sort of have errors occur here and then i'll sort of cover them but first let's just make it a little bit simple let's go and create a thread and a main thread and execute and you'll be able to see how they trade off time so to create a thread we're going to use spawn so we're going to say thread and spawn like that and this is actually going to have a closure inside of it so there is our closure and i'm going to cycle through and have it share outputting information to the screen so let's say we want to do this 25 times and i want to say just print line just to keep it very simple i'm gonna go and say spawned thread this is gonna there's gonna be a spawn thread and there's gonna be a main thread and both of them are going to be outputting information on the screen you're gonna see how they don't necessarily always do everything in time and now what i'm going to do is i'm going to force this thread to sleep after it prints this so i'm going to say thread and this is going to give our other thread the option of going in and executing so i'm going to say from and i'll just say one millisecond so no second and one like that and there we go okay so that's going to handle that and we have this guy right here now what i'm going to do is i'm going to also outside of here going to just inside of our main thread this will execute so i'll say and 1 to 20 doesn't they don't have to be the same and we'll say actually i'm not making them the same on purpose just so i can show you something else so i'll say main thread notice specifically that this spawn thread has 25 times it's going to print and this only has 20 times it's going to print very important for what you're going to see here in a minute so i'll say that i want to go and print that and then i want to also put this thread to sleep for one second so like this like this and like that and we'll run it okay so here are our threads running you can see there's a whole bunch of things going on so we have our main thread is going to execute and it prints out one then you have the spawn thread main and then you have the spawn prints twice then the main prints two two two times and then it goes down and it gets down to the spawn threads prints out to 20. but you may say to yourself wait a minute this is supposed to print out 25 times only prints out 20 times and this does print out the actually it prints up to 20 but doesn't include 20. so what exactly is going on here well there are no guarantees on when threads will execute and if they will even complete execution in this current form however if we want to guarantee that they do execute we call join so we're going to say thread one dot join and then what join's going to do is it's going to make sure that both of our threads are going to be able to complete and then after this we're going to call unwrap which we've seen also before and that's just going to handle the result that's passed back but one thing we need to do is come up here to the thread part and say let thread 1 equal to thread and that's gonna handle that okay and if we come in and we run it now you're gonna see that both threads are going to complete all right and let's just get rid of that and there we go both threads were able to complete in that circumstance but let's go and actually see what this looks like by actually using this type of a sort of a real world example so what i want to do is i want to sort of create a bank account and then have multiple different customers all try to withdraw money from said bank account so i'm going to keep this very simple this is just going to be a struct it's going to be called bank and it is going to just have a balance inside of it and there it is it's a float and then what we want to do is we want to be able to come in here and withdraw money from it so um like i did before we're going to get errors and things aren't going to work right and then i'm going to walk through exactly how to handle this so this function here is going to be passed a reference to our bank and so this is going to be mutable bank and it's going to be past an amount to withdraw i'm going to move this over here so that we have plenty of room so it's going to have an amount and that amount is going to be a float and then simply what i'm going to do is just say the bank minus equal to whatever the amount is they want to withdraw from it and just keep that simple and you're going to see errors are already popping up here what's this error say binary assignment cannot be applied to mutable bank cannot use on this type oh that doesn't have anything to do with anything i just forgot to type balance in there okay so no no errors yet okay so let's continue so what i want to do now is i want to create a bank struct so i can just go like this and it's going to be mutable because we're going to be changing some things here and i'm going to say bank and i'm going to give it a default balance whenever it's created which is going to be equal to hundred dollars so we're gonna say that we have a hundred dollars in our bank to start out with and then we're gonna start taking money out of it and then we're gonna come in and we're gonna say that we wanna withdraw and we're gonna pass in our bank inside of here and we're going to withdraw five dollars and then we can come in and say print line like this and balance and like that and go and get our bank balance so bank balance and there we go and if we run this we're going to see that our balance comes back as 95 okay so everything's working so long but one thing we want to do is we want to create we want to demonstrate concurrency here so we want to create a bunch of customers that are going to withdraw money so we will once again come in and we'll say function and we'll call this customer and it'll have a bank reference and this is going to be mutable bank type and run this and then we'll call withdraw from inside of here and pass in our bank and our five dollars that we want to take from it okay uh oh we're starting to get some problems and this says that we cannot capture dynamic environment in a function yep this is b this is bank like that sorry okay got rid of that problem okay so now what we want to do is we just want to create our our thread which is going to have a customer go and withdraw money from the bank should be easy right let's do this so we'll say spawn and this is going to be just a closure and i mean everything looks good here right i mean why shouldn't this work so we'll say customer and mutable and bank and then after this we will go and get this guy down here and you can actually just go join like this and unwrap you don't have to do it the other way nice to show different ways of doing stuff and then we come down here and like that now the problem that we are having here with this code is that basically we're borrowing now let me explain in another way you can't have a situation in which a closure may outlive the current function and especially because it is borrowing which is owned by the current function so in a situation in which a thread can outlive the main function and the main function has the bank this obviously is going to cause all sorts of different problems now one of the fixes for this is actually a smart pointer and this is a smart pointer that's going to allow multiple owners and it's also going to block access whenever these different parts are needed and what we're specifically looking for is the smart pointer that is going to have a reference and what we're specifically looking for is a reference smart pointer so let's just delete all this let's just get rid of everything except for the bank structure here that's still okay and we'll be able to work with it now we're going to have to come in here and import a couple other different libraries i know i'm starting to get a little bit more complex complicated just wanted to sort of end by covering smart pointers here all right so we'll go use and standard cell reference cell and another thing we're going to need is an atomic reference counter which is going to provide shared ownership of a value so we'll use like this and [Music] we'll get arc and then also we'll use mutex and mutex is going to block threads that are waiting for lock to be available and this is in standard oops forgot to put standard inside of there there we go all right so we got all this set up okay so the only thing we have left is our bank structure and let's go and simulate this whole bank transaction so what we're going to do in this circumstance is we're going to go function and we'll use our withdrawal function just like we had before and it's going to be receiving a bank and now we have to say and arc like i said it's going to provide shared ownership of a same value mutex which is going to weight or block threads from being able to access until it's available and then we'll throw our bank struct inside of there at the end and this is also going to receive some amount like this put space inside of there okay so we have this set up now we can say let mute and get a reference to our bank by saying the bank dot lock and unwrap and we'll be able to go in here now and we could do some checks to make sure there's you know actually money in the bank so we can say if bank reference balance is less than five dollars remember we're taking five dollars out each time i'm simplifying this obviously uh print line then we could say something like current balance and show the current balance and then say withdrawal obviously i'm making this extremely simple a smaller amount and we could go bank reference and get our balance and display that on the screen and otherwise if we have money in the bank we can go bank reference balance minus equal to whatever the amount is they want to withdraw from the account and then we can go and print some information out here so we'll just go paste that in there and we'll just change what this is so we'll say something like customer withdrew and how much money they took out and then we could list our current balance once again and then at the end of here we'll just go amounts like this and like that and that's good okay so that's our withdrawal function and how we were able to change some different things to make this work so that we can properly borrow and lock down our information now we're going to be able to go function customer and the bank again we're going to use this guy up here let's just copy the whole thing copy and paste this inside of here like that and that's all that's going to be passed to this and then we'll just call withdraw from inside of here and pass the bank and the amount to withdraw right like that and what else would we like well we're going to have to create our bank and did i save that i hope so boom uh so they have part of it so let's get this out of here and we will go and this will be equal to again arc new whoops new like that new text new bank and pass our balance inside of here to create our bank instance and we'll say we have 20 dollars in bank we're obviously very rich accidentally put a reference there let's get rid of that okay that problem solved and now what we need to do is let's just create a whole bunch of customer threads so i'm going to say let handles equal to and uh let's go zero let's create 10 of them then we can call map on this and there we are and let's run this and what we want to do is go and create a bunch of clones of our bank so we'll say let bank reference equal to bank clone and then go thread spawn like we did before and then inside of our curly brackets we'll just call customer and pass the bank reference over and over again and throw in that semicolon and then what we just need to do is wait for all the customers to finish and we can do that all at once with all these different threads that we have here by just going handles like that and handle dot join and dot unwrap i showed you three ways of doing this okay and like that and then at the very end all of that information is going to print out but then on top of that we're also going to output our final balance so we can go and go bank dot lock dot unwrap dot balance to get our final balance from our bank account and let's get rid of that little quote there and if we come up here and we run it all boom you're going to see that the customers were able to access and you can see that the balance is dwindling down to nothing and then eventually the balance goes down to zero and they're no longer allowed to access or remove information or remove money from the bank okay guys so there you go that is a rundown of countless numbers of different things with rust like anything uh just work through the problem experiment and then go on to the documentation and check it out check it out and look for some of the different functions that i was just unable to cover just because of time limitations but i think this will give you a big jump start when it comes to learning how to get very good at rust as per installing rust all you do is go to rust rust.lang.org and tools install whatever just go to rust.lang.tools and you'll be able to install just by clicking on install right here and on macs and linux all you need to do is go into your terminal copy and paste this directly inside of here and if you are on windows you're going to need the microsoft c plus plus build tools which more than likely you have just type in microsoft c plus plus build tools to find this specific website you're going to download those then what you want to do is you could go to rust up dot rs and you just click on this little executable that comes up right here if you're on windows this is going to try to protect you say run anyway and you're going to automatically open up your command prompt and a whole bunch of things are going to execute you're going to proceed with installation and then a whole bunch of different things are going to be downloaded and installed for you then what you're going to want to do is go into visual studio this is going to apply to mac as well as linux users if you want to use visual studio code you're going to click on extensions just type in rust you're going to see rust analyzer show up as one of the options you're just going to click on install and here is rust analyzer everything has been installed this is going to handle everything for you then if you want to verify that rust has been installed you can open up your command prompt type in rust c dash dash version you should see something along those lines anytime you want to update rust you can just type in rust up update and of course if you want to create a new rust project you just type in cargo new whatever you want to call it you can see the directory structure that we have inside of here just like we did previously and of course if you open up that code or that project inside a visual studio code you'll get your hello world and then you can execute it just by clicking on run so there you go everything i got on rust if you want additional information leave it in the comments down below and like always please leave questions and comments down below otherwise till next time
Info
Channel: Derek Banas
Views: 504,638
Rating: undefined out of 5
Keywords:
Id: ygL_xcavzQ4
Channel Id: undefined
Length: 155min 11sec (9311 seconds)
Published: Fri Jul 29 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.