Go (Golang) CRASH COURSE | Scott Reese | Skillshare

Go (Golang) CRASH COURSE

Scott Reese, Engineer & Investor

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
7 Lessons (1h 57m)
    • 1. Welcome to Go!

      2:13
    • 2. Go Basics Part 1

      15:23
    • 3. Go Basics Part 2

      19:28
    • 4. Go Basics Part 3

      26:01
    • 5. Methods and Interfaces

      29:24
    • 6. Goroutines

      22:15
    • 7. Course Project

      2:26
14 students are watching this class

About This Class

Welcome! The Go (Golang) programming language is gaining rapidly in popularity and adoption throughout the software development industry. Mastering it now will give you a head start and help you stand out as the language is still rather new, yet demand for Go programmers is increasing! This course will give you a quick overview of Go syntax alongside some of its primary features and functionalities. I highly recommend watching this course carefully, taking notes, and also working your way through the official Golang online tutorial (link down below). Using these two sources will ensure that you feel very comfortable with the language after completing them and ready to start creating Go applications easily and efficiently. So let's get started!

Link for online tutorial: https://tour.golang.org/welcome/1

Transcripts

1. Welcome to Go!: Hey there. So I assume that by clicking on this course you haven't interesting and potentially learning the go or Golan computer programming language. And this is great because Go is currently a very rapidly growing language in the industry, both in terms of its popularity and its adoption rate in the software development world. And even though it's going quite rapidly, it's still not quite as prevalent as, let's say, Java right. And so if you can master this language now, it'll be a great way for, you know, if he puts on your resume to help you stand out amongst the other soft engineers, Web developers, computer programmers, etcetera, right? I designed this course to give you a very efficient and quick overview of the ghost syntax and some of the basic features and functionality the language so that in about an hour you could be pretty up and running and ready to go to write some go code on your own. Now, I also designed this course to closely follow the official go tutorial online, and I have linked that's tutorial in the description of this course, and I'd highly recommend you watch this course, obviously, but then also alongside that. Work your way through that tutorial. In my opinion, when you have two sources that you're trying to learn from in order to master a certain skill maybe one source that's more text based, which is how the tutorial set up. And Amora visual source. I e. This course using both of those things will really help solidify your understanding of whatever it is you're trying to learn. So, um, just a little introduction as well. My name is Scott Reese, and I'm currently a software engineer myself working in the financial services industry. And currently I write go code almost every day. This is something that I had to learn quite quickly because prior to this job, I had no go experience whatsoever. So the only tutorial was one of the main ways I taught myself go programming. And like I said, this is something that I recommend you work through alongside this course. And if you do both those things once you're done, you're gonna have If you're gonna feel very comfortable with this language and you'll be ready to start running applications of one not and go completely on your own. So without further ado. If you still have interest in learning this language, then let's get started and dive into some go code. 2. Go Basics Part 1: alrighty. So the first major component of this course is going to dive into the basics of go. You know, the syntax, the basic features and functionality kind of things you can do with the language and all that. Not super fun stuff, obviously. But, um, these are the kinds of things that you should understand and nail down first, because they're gonna be the building blocks on which you can use to build full fledge applications and go. So in this first part, you know, there's a lot to cover with the basics. So I divided things into three parts. This is part one, and this one we're gonna be talking about packages, functions, variables, basic types and tech conversions. And Constance, So diving right in, uh, starting with packages, you can see we're at the gate here. We have this package made at the top of this code file. If you're not familiar with the concept of a package in programming languages, the package is essentially just a construct that allows you to group multiple code files that are typically related in some way, maybe in terms of their functionality or that kinds of calculations they perform or use cases, and things like that allows you to group them together under, ah, one single identifier and common example is you know, let's say I just want to print something out to the terminal. So if I just wanted Teoh print, you know, famous example. Hello, world. Right, if I can spell this correctly. Jeez, um, so yeah, versatile example. It's one pronoun hello world to the terminal. And, you know, I gotta make a function called to do that, which is located in another package. Right? And that packages the FM T package. So this function is somewhere else in this package called F 20 and I'm allowed to reference it with this kind of syntax. You specify the name of the package, period. In the name of the function, you want to actually reference in use to perform some action. And, um, one thing to note is, you know, and or if you do, reference that function or variable and in turn package, the name of that variable or function has to be capitalized. This is just goes way of, um specifying which functions can be referenced outside of a package and which functions can not. So If this print line function, for example, started with a lower case P, that would basically mean the only functions within the F M T package will be a lot of access. It, um if that was the case, you know, since I'm in a different package package mean I would not be allowed to cola's print line function, but because it was, um, written in the F 20 package with a capital P. That basically just means I can call this function anywhere in any package. Um, anyone? The application. So just something to be aware of. And one more thing with packages. Every girl application has to have a package mean. And this is going to basically specify the general entry point of your program where things were going to get started. You can't have multiple files in your package. Main right. Maybe you have a whole directory. That just is package Maine, and you have all your different code files in there that are all related in some way. Um, you want put them in the main package, but you always have toe have exactly one main function, and this is gonna be the specific entry point of your program. This is where it's all going to start. So just give in mind wherever your program starts. Has to be in package main. It has to start from this function mean, um and so going into functions. Now, um, you know, just in case you're not familiar with the whole concept of functions and you know, these modular pieces of code and things like that, a function is just simply a reusable piece of code, right? You know, if I had a function with, you know, many lines of code in it, for example, and I needed two reference these lines of code multiple times use them over and over again in my funk in my program would be pretty tedious staff to write out the same exact lines coat over and over and over again. Right? So with functions you can simply write those lines of code within a function and simply referenced the function by its name. Right? This is exactly what we did here with this print line function. And we can reuse this this chunk of code over and over and over again just by referencing the name of that piece of code which is, you know, a very efficient way of of doing things right. And, um so as an example, we'll make a little function here. Let's say we just want to, um, add two numbers together and return the result. So to declare a function and go, you start out with funk, then the name of the function, so we'll call it ad. And now you want to specify your input arguments. So we're gonna take in two numbers and what was called an X and wife. Right? And I'll get into the syntax in a second, right? Those are gonna be within your closing parentheses. Andan. You specify the return type and then your brackets. So going to the syntax here for your input arguments, Um, go is a little bit different than maybe you know, if you are more familiar with java or C or something like that, where you typically declare the data type first and then the variable name goes backwards, you declare that variable name first and then the data types. So variable X is imager. Rebel. Why is an edger and dysfunction returns an integer So you just say return X plus y right And there you go. And one at a little trick or shorthand is You know, if you have multiple arguments in a function that are of the same data type and they're in sequence like this, you can simply omit um, all the data types except for the last one. So this now basically still be compatible and everything will work. And you could read this. As you know, variables X and Y are both imagers, you know, just little bit shorthand. I typically like to just still specify the data types of every variable just to make things explicit. But up to you. And so now we have a function that we can reuse over and over and over again, and we just simply need to reference it by its name and then specify some input arguments. And as an example, you know, typically, when you have a function that returns some kind of value back to you, it's common to store that result in a variable, right? So, you know, I do let go for a lot of reasons. But one of the one my gripes with go is the amount of different ways you can declare variables and you'll see what I mean in a second. So the first way you could declare variable. And it's the most explicit way of doing so. It's type far variable than the variable name, so we'll call it some. And then it's data type, right? This lying just specifies that you know, I have a variable summits imager haven't assigned a value to yet, but that's what it is. And then we need that. I can say, OK, now some equals Add one to right. So you know this is gonna call the ad function with the inputs one and two. This ad function is going to return the some, which is three and then three is gonna get stored in the variable some right? But obviously, you know, this is a two step process. It's explicit. It's pretty clearly understand what's what's happening here. But, you know, why do I need to write two lines of code just to make it variable, right? It's kind of tedious, so you can do it this way. But a shorthand version is just do bar some equals and then the function call right there, right just like that, or you know, you can make it just ah, literal three if you wanted to, but just kind of combine the things were learning here, Um, so this is the mawr shorthand way of doing it. And you can see, you know, I've omitted that imager data type declaration right There are no longer needed it. And this is because that compiler was smart enough to know that, you know, for calling this ad function, it knows that the function returns imager. So it's gonna basically say, OK, some is not gonna be interred your as well, so its able to make that connection, which is pretty neat. Um, but there's also an even shorter way of making variable. So instead of doing this, you can simply do some, uh, colon equals. Add 12 and this is the most is the shortest shorthand way of declaring a variable and go right whenever you're. If you want to do this way, whenever you're declaring a variable for the first time, which we are doing here, you need that colon equals and then you can assign it whatever value you want and the compiler again, it's small enough to know that this is a variable It's imager, everything's good and, you know, then laid it on the road. You can change it. I changed the values, Whatever you want. No, change it to five, for example. And in this case, you don't need that coal anymore. Only you only need that the first time you're declaring that variable, and you can change the value any time there after that. So this is how I typically create variables and functions. But, um, you can on Lee use the syntax within functions. That's one thing you must keep in mind. If you want to use the shorthand, you can only use this with inside of function. If you want a global variable, right, that's access that can be accessed from any function in the in the code. You still use the var statement and you know you I think I believe you can just, um, a sign it right away. I think that, um, but you do have to be much more explicit with your global variables than, um, your your your variables within a function. So you know, as you can probably see, you know, is kind of confusing or potentially confusing with how go allows you to create variables in so many different ways. But typically, you know, my rule of thumb is, you know, within a function I use this global variables. I'll do it this way, you know, just keep it simple and consistent, but yeah, a little bit confusing. Withhold your different options. Um, that's variables. And then going into all the different types, data types that go offers. So, you know, if I wanted to speak in the little variable here, so there's different kinds of images right years. There's your typical image or data type, but you can also get very detailed and how you specify how many bits are used to create this image of variable 16 bits 32 bit 64 8 A lot of choices here. There's also you went data types for unsigned integers imagers either zero or greater positive. And you can also specify 16 bits. 32 bids 64 8 and all that. You have your strings right for text variables, right? How the world as an example. Um, you have your billions right for your true and false variables. Just bull for short. Um, you also have float that you float 32 bit on float 64 bit. These were going to be your decimals, right? And then, interestingly enough, go also offers complex data types as well. So you have two options with complex data types. I personally, um, don't I've never had a need to use these before, but it's kind of cool that they offer this throughout the gate. Um, and then you can also, you know, typecast as well. And go, which means, you know, if I have and variable that's imager, I can create another very bowl that, um, could be a decimal and convert the value of that initial variable to a decimal socially with example here. So if I just had a simple variable, um A. And I decided, while you have one like that, that's the imager is one. It's imager. But if I'm making in the rebel F and I wanted to be decimal and I wanted to be the same value as a right, So f is also going to be one just like a right what's gonna be stored as a decimal? So 1.0 32 bits of that and you know you can do this with float 32. You can do this as a you know, You went in 64 right? All works the same way. So just ah, offers a very simple, clean way to create new variables based on the values of other variables. And you're able to change. Um, you know how these things new variables are stored. Right? So, um, interesting. I don't like something that I've used many times with programming. So keep that in mind. And then the last thing I want to cover in this video is constants. So for a constant, you simply declared as const. The name equals, and then whatever. Right? So, um, you'll notice there's no need for ah, Colon equals here. It's just a straight equal sign. Another little weird quirk of go. Just something gotta remember. But that's all it is. And, you know, if you're not familiar with the concept of a constant, it just means that, um, you know, you cannot change the value of this constantly in Iran. So, you know, um, with this example a was defined to be or was assigned to the value one later on in my code , I can change us did anything else? I want to change it to three. Right? But if I tried this with my constant try to change it to five, this would cause an air, right? The program would execute that, get to this point, and then it would cause an air and it would not finish. So just keep in mind if you ever want to be, you know, safe. And make sure that a variable never changes. For a certain reason, you just declared as a constant like this, and it'll guarantee that I will never change, or else your program will just terminate with an air. So, um, I think that wraps it up for part one of the basics. And in part two, we're gonna start going into four loops if statements switch statements and the first statements. So more super awesome, exciting stuff. But as I said, very important to understand all this stuff for at the gate. So thanks for watching this one. And I'll see you in the next one. Thanks. 3. Go Basics Part 2: All right, Welcome back to part two of go basics. And as I said in the previous video in this part here, we're gonna be discussing, uh, four loops if statements switch statements and defer statements and go So just diving right in getting started with four loops. You know, if you ever programmed in C or Java before or really any flavor or variant of C four loops and go are gonna look very similar. In fact, they're they're almost identical. So and go to make a four loop, gonna have your four key word there. Then there's going to be an initialization statement. So make a very bold called I initialize it to zero. Well, just safer. I less than 10 I plus plus. And then let's say we have, you know, some variable called some that we define outside the four loop. Well, just initialize it to zero, and then inside the for loop, you know, we'll just dio some plus equals I, you know, very simple. So, um, all this is doing in case you haven't seen this kind of syntax before is we've got a four loop, which is just kind of an iterative piece of code that's going to repeat the same piece. Um, until a certain condition is meant in this case, we have a very book called I that we initialized to the value of zero. And as long as I is less than 10 we're going to increment. Some is variable outside the for loop by the value that of I. And then every time this loop iterated we're going to increase I buy one, right? So you have the initialization component The conditional statement in the post action statement. This is just saying Every time the loop illiterates increase, I buy one. So, you know, as an example here some a zero I starts out of zero sown when the this for loop it reached for the first time. We're just saying, you know, increments some by zero. So, you know, 000 nothing changes there, Then loop in rates. I becomes one and now we're saying it commits some by one on the Lipitor. It's again, I becomes, too. And then we increments some by two and so on and so on and so on until I becomes equal to 10. And now that eyes no longer less than 10. This Philip is going to stop executing, and any code after the for loop will start executing thereafter. Um, one thing to note. I mean, if you do have experience sincere java, you do not need parentheses like this. You know, seeing job require this kind of syntax and go. You can simply omit the parentheses, stoning the brackets. But this perfectly vowed ghosts and tax here. One thing to mentioned, though, is go does not have any wild loops. Everything can be done with the for loop itself. So the way you would convert this kind of set up into a while loop is, you know, the initialization peace and the post action component are actually optional. So you can omit those two pieces right there, Mr Components of the four loop. And let me just change a couple things here will just say for some less than 10 some plus plus, right? So this is basically how you would make a four loop and go. You could read this as while some less than 10 increments, some by one. Just keep doing that until some becomes equal to or greater than 10. Um, but for some reason Google, the creators of Go decided that we're just gonna not include the wild keyword. And everything can be done with a four loop. Just maybe keep things more simple. I don't know, but that's how you would do a while up in the situation. And one other thing to keep in line is to make an infinite loop. You can actually omit the conditional statement altogether. It's now this loop is this full of is going to get a rate forever. Just keep iterating some by one over and over and over again. So obviously, if you want your code terminate at some point you're gonna want to break out of this loop and you would do so with a break statement. Right? Um, there's also a continue statement to and typically in the set up. I guess this would be good Segway into, um if statements and conditional statements, um, so I mean, if you have experience programming of the languages, you know, if statements were quite common and in go, it's a very similar kind of set up in terms of syntax. We basically just say, you know, if some less than 10 for example, maybe we break, right. So, you know, when the slope starts, executing some is initially zero. And then we're just gonna keep in committing some by one. So some becomes one, then two, then 34 And just getting to know this loop just keeps going forever. But we have this if statement here that says, Well, once some Excuse me, I messed up here. We should say, once some becomes greater than 10. Um, so once some is greater than 10 then this break statement will execute, and this whole four loop will stop running, and any code after the loop will begin executing. That's how you would use a break statement in this case on before the continue statement. Let's say maybe, um, I'll see if I can come up with an example here. Go also offers else if statements as well as l statements just like most of the languages do. Um, so maybe you have a couple conditional statements here. Maybe you know, else if you know, if some is equal to 10 in the first statement is if some equals five else, you know, just do something else. Right? So now we have a couple of conditional statements here. And maybe, you know, once we have some equals to five, we just want Teoh, uh, continue. And so, you know, maybe we have some coated down here, for example. Um, and this code would execute after all, if any of these if statements occurred or if they didn't occur. Right, Um, if you have any code done here, this will always be executed any time this for Lipitor rates. So if whatever reason, you don't want any of this code on here to be executed of some equals five, use a continue statement, which basically says, in this case, if somebody will go five, just skip everything else in this loop and then escorted back to the top and start over, right? And then maybe, you know, if some becomes equal to 10 we break out. So this is, you know, a pretty common kind of Sepp. You would see maybe with an infinite loop. You know, you have some if statements in here that check certain kinds of conditions, and once a certain condition is met, then that's when you would want to actually break out of that loop and then start continuing on and executing more code there after. So like I said, I was a pretty good Segway into discussing conditional statements if statements and all that kind of stuff, Um, one other cool thing go offers with if statements is and I believe other languages, like I think, see and even job and maybe offer this as well as you can. You gonna have, uh, what's called short statements within your your if statement what I mean by that is let me just get a clean slate here. Um, let's save. We just have an if statement that is actually able to initialize variable called some, and we'll just say some gets initialized to the output of some function we call function right? It's just some function is to find elsewhere. And when it's call, it just gives us back a number and that number gets stored in some. And then we can say enough's some less than 10 be. I want to do something right. So this is cool because it allows us to, um I think my indentations off here on second. There we go. This is a cool future because it allows us to create a new variable called some initialize it and also perform some conditional checking on it all in one line. And, you know, if this is the case and some of less than 10 then we would obviously execute whatever piece of code is within this, if statement so pretty nifty feature. I think death is something that I've used a couple times. So I'm glad um, go offers that feature, and I believe that covers it for if statements saying conditional and things like that. So now, going into switch statements, which is another pretty common feature that most languages provide. So similar kind of set up, and we have a very called some Let's say it's it's initialized to the to the result of some function output. And now they want to do, ah, switch statement on this so and go. It's very simple. You just do switch some, and then you have your cases. So maybe case, you know, 50. Um, Well, do something. Uh, case 100. Well, you do something else. Case 2000. Do something else and blah blah blah. So you get you get the idea here. Um, you know, switch statements are great because, you know, you could do this with if statements you could have. You know, if some equals 50 do something else. If some equals 100 do something else else. If son equals 2000 do something else and so one right. But you'll notice if you have a lot of statements that you need Teoh, A lot of conditions you to check using ifs, and else it's will get very lengthy on tedious to read. So a switch statement allows you, You know, um, compact all that code into a very nice, smaller, easier to read piece of code. And if you haven't seen switch David's before, um, you know, all this means is we're performing some conditional checking on the value of some variable . And these cases basically act like if statements. So this basically means case 50. If some equals 50 do this. If something was 100 do this and so on. And you know, none of these cases air true. Let's say some is like 10,000. You can have a what's called the default statement, right? And you know, if this is something that's kind of your your fallback operations stuff, none of the cases are true. if some doesn't equal 5100 or 2000 and you have a default statement specified here than this piece of code would execute And one thing to keep in mind, um, with ghosts, which statements as compared to switch statements in Java or C is, you know, in Java and C whichever case is true, let's say some is equal to 100. And let's say we're talking Java here. This, uh, statement is true, so this code will be executed. But then the next case would also be executed. And then any cases you have defined their after all that code will be executed. And if you don't that I don't want that to happen, then job are See you on the way. You would fix that as you have a break statement right here. So, you know, if someone 100 this case would execute, you know the code here would be executed, and then you would break out of the entire switch statement and then any code that you have after the switch statement would execute can go. You don't need a break statement at all in go. They decided to design this in such such that whichever statement or whichever case is true Onley That case is executed and it is only executed in the nothing else. So just keep that in mind if you're using switch Davidson, go. You do not need any break statements within each case, Um and that covers switch statements. And so the last thing we want to talk about in part to hear of go basics is the the first statement, which is, I believe, a ghost specific future. And it's more of just kind of Ah, uh, nice toe have feature. I don't personally used a whole lot, but is it does serve a purpose if you want to leverage it. And so the way you would use it. Just getting example here. No, we'll just do a simple capitalize that the world was printed out to terminal. Maybe will make a very book called some again in this last one on. We'll just print that out to Terminal two. Right? So here's our little set up here. So the first statement it it's it sounds you know exactly how it behaves. It will defer the execution of whichever line of code balls it until the surrounding function returns. So in this case, this print hello world function call will not execute at this point in time, right? So when the the program is executing and it gets to this point, hello, world is not gonna get printed out yet. We'll go right over to some making variable called some a sign that the value of one and then we will print out some to terminal will print out one, and then at this point, the main function will return. And it's at that point that hello world would then be printed out to terminal. So it differs the execution, As I said of the line of code after it, always until the end of the function until the function is ready to return. Um, so you know, you could do something like this, but you can also just, you know, if you want to tell the world, put it out last, you could obviously just pull at the end, right? And this would output, um, one first and then hello, world. Just as the previous example. So, like I said, the differ statements kind of just a nice toe have feature in my experience where I've seen it being used is, you know, if you have a file that you want to open and read data from and you have to open that file and then it's typically good practice to then later close that file when you're done. So it might be mawr convenient to have Lana code that opens the file, and then right after that, you say differ file dot close. Right Just allows you to make those file file system function calls right together to make sure that you have both pieces and that's really old. The only benefit the the first statement will give you, in my opinion. But, you know, it could serve other purposes if such such situations arise that you may encounter. So just keep in mind Could be nice to have but nothing, nothing critical and that Oh, yeah, Before we conclude this video, one last thing I want to touch upon is you know what? If you have multiple the first statements in a function so you know, for example, let's say we have another four loop. I'm just know frankel. Zero I less than 10 plus plus same set up as you've seen in the beginning of this video, let's say within the for loop we have in the first statement Bryants or get a little bit more fancy here. And so this loop is gonna reiterate 10 times and we're going to defer this print statement 10 times. How How is this gonna behave? Well, differ statements, Whichever lines of co you are quote unquote deferring until the end of the function, all those statements are gonna be placed onto a stack. And if you're familiar with the stack data structure, this functions as a last in first out ordering right? And what I mean by that is you know, the first time this loop generates, I is gonna be ableto one. And so you're going to defer the printing out our shoes. Me, Eichel zero. It's all right. And you're going to defer the printing out of zero and then the lips going in, right? I then becomes one, and then you're going to defer printing out one than I becomes, too. They're going to defer printing out to and I becomes three. And so on your you just keep stacking up these differ statements. Well, once I becomes nine, which is the last time this loop is going to reiterate you're going to defer printing out nine. And that's the last statement you are going to place on that stack. And then this loop is going to break. It's gonna execute any co you have thereafter. And then the surrounding main function is going to return. At this point, that's when all your differ statements are gonna start executing right. But because they are placed onto a stack, the last statement that got put on the stack is gonna be the 1st 1 out. So when you're deferred statements executing, they're going to basically execute backwards. So nine is gonna get turned out first than 8765 all way down to zero. So even though the full loop was going in reverse border 01234 up to nine. The differ statements get executed backwards. So just keep that in mind if you have a set up like this where you have to first Davidson a four loop Or maybe you have, um, you know, multiple the first statements in your in your function itself. Just know that when the function returns, they're going to be executed backwards right, So just something to keep in mind if you ever want to use it. The first statement. That's how it's going to behave. And that should wrap everything up for Part two of go basics. And in the next part, the final part of the Basic stuff ago, we're going to be getting into some more complicated things. Go does offer, for example, the usage of pointers and Struck's and these things called slices, which are a go specific feature. And these things have some or nuances and sell teas and can be a little more complicated to understand. So, um, and just as ah, is ah, warning you take your time going through this next part. But it is going to be, in my opinion, more interesting to learn more interesting to learn about these things. There's a lot more you can do with pointers and Struck's in slices, and so you'll be getting good exposure. Tell that a swell. So congratulations on finishing part two here and I'll see you next. One for part three. Thanks 4. Go Basics Part 3: already. Welcome back, Teoh. Part three of three of go basics. And in this video, as I mentioned the previous the previous part, this is where things are gonna get a little bit more tricky and nuanced many because, you know, we're gonna be going into pointers and struck's and slices on a couple things that are just inherently a little more advanced. So, um, try and be as detailed as possible, but not go too far in depth just to be one respectful of your time, cause I don't think so too long. But also, this is just a introductory kind of course to go. So I just want expose you guys to the high level stuff. So kicking things off, we're going to start talking about pointers. And if you have done any C programming in the past, for example, this might be ah review for you. But if you are unfamiliar with a pointer, a pointer is essentially another kind of, uh, data type that can store memory addresses, too. No, our that memory dresses that hold different kinds of other data types and so the best way I can walk it walking through this is the an example, So I'll just say I make it variable in this main function called Numb and all Sign it, the value of one right So numb is one. I could make another variable called you know, Numb Pointer for short or PTR for short. And the key here is we use this ampersand symbol fall by the variable name Numb. So what does this mean? We'll numb is a variable, right? And it holds the value one. It's an integer, but everything that is held in memory, that's where no mist or it has to be held in memory. Somewhere it's in this case would be held in ram random access memory and every piece of memory has an address to it, right? This is how the operating system, for example, knows where everything is because everything is addressed. Everything has, um, a number associate with it, that is Theodore s. And so this ampersand symbol simply means I want you do take the address, the actual memory address of numb, wherever this is stored in memory. And take that address and store that into this other variable called none Pointer. So you know the address of Numb. I'm just making a number up here. And this is memory dresses air typically represented in Hexi Decimal. So I'm just going to say, you know, uh, to a 56 b c d. Um, See, it's 1234567 okay ago. So, typically, memory dresses are, you know, hex decimals. Eight characters long like this start with zero X and whatnot. So this is just address, right? I'm not gonna go into the details of what is this exactly mean? And how do you convert Hex? A decimals to a natural number and things like that. But just take this as the address somewhere memory of where numb is stored and this ampersand symbol assembly saying Take this address and store it in None. Pointer. So none pointers variable. That now holds this value right? And so what you can do with that Azan example is using a pointer. I can now go in and change the value of numb just by having its address on hand. So again, through example, I can say star none pointer equals three. So what does this mean exactly? Well, we first made a variable called Numb and we gave it the value of one. We then made another variable called Non Pointer, which holds the address of Numb. And with this statement here, we're basically saying I want you to go to this address wherever it is a memory and change the value that stored there from 1 to 3. So, for example, you know, power to just print things out right out of print, out numb here. And then if I were to do the same thing again here, right in this case, NUM would be printed out as one. In this case, Numb would be printed out as three. Because with this statement, I went to the actual address, the location of this variable in memory, and I actually changed the value to three. So that's the whole concept concept of a pointer. This is how you can one make a pointer, right? This is this is how you, um, take the address of an existing variable used the ampersand symbol, right? This basically means give me the address of this variable and then through the star. This is how you access the value stored at that address. Right? So these are the two symbols you'll just have to keep in mind when you're dealing with pointers and whatnot. So again, I'm not gonna go until the details of you know all the different use cases of pointers pros and cons, things like that. I just want to expose you guys to the syntax and just explain what this is, right. And then you can do your own in depth exploration later. If you so choose that's pointers. The next thing I won again two is Struck's, which are basically containers that can hold a variety of different data types and variables. And things like that just allows you to pack package up, um, a set of attributes in under one name. And I'll explain this third example as well. So you know you can define a struck either with in a function or globally outside of functions. Um, either ways totally valid. But typically, I see the mostly to find outside of a function or defined globally so that any function within this file, or perhaps other, could files that, um, media access to this kind of, uh, object or data type. They can use that as well, so I'll just define it globally. The second this example. So let's say we wanted to find a struck that's, you know, gonna be that's gonna represent a dog. So to declare instruct you do so by saying type dog typically want to capitalize the name, fall by struck and then brackets like that. And then you can add attributes to this kind of this dog struck so we can add a name, for example. That's gonna be a strength. We can then add maybe an age, which is an integer we can add a new owner, right? That's, you know, the owner's name, for example. That's also going to be a string. And so no, here we go. We have defined a dog struck, which is essentially just a container of sorts that holds a couple things. A name in Asia. Owner. Right. And keep in mind, though, this is just doing this right here is just declaring what a dog struck is. We haven't actually made any variables, um, that are dogs or anything like that. So once you declare what this type is now you can go into a function, for example. And in Stan, she ate a dog, and I'll do so right here. Um, excuse me. There's a couple ways you can make it variable, that's of type dog. And you know, the more explicit way of doing it as you've seen before is far. Just call it, you know, dog dog like that. So we've declared a variable. That's the variable name is dog, and it's a type dog. And then what we can do is through dot notation is what this is called. You can do the name of the variable dog period or dot and then you have, as you can see here, you can have access to all the different attributes. So you can say, you know, dog dot name or capitalize it name equals, uh said Charlie, and then we can do dog dot Age equals three dog dot owner Say I own the dog. So Scott, right? And so now this is This is exactly how you declare a dog variable us sign its attributes, some actual values. And then, you know, maybe you just want toe print this out or something like that. And you know, this is this will print out the dog variable. The dog struck that we've made won't do any fancy formatting to make things look pretty, but it will print out in some fashion these three attributes. So that's the more long version way of declaring a dog struck, Um, or shorthand way of doing it is just doing Dog Colin equals uppercase dog brackets. And then within here, you're going to say name Colon Charlie and then comma Age Colon three comma, uh, owner Colin Scott, right. And this allows you to declare a dog, struck it and settle its attributes to the values that you want in one land. A coat pretty neat. So I want to get into a raise. And you know, if you have any programming experience, especially with modern day of programming languages like Python, Java, Sea, even go so they all have a raise, which is just the most were the most simple data structures that you can possibly work with . It's simply just a container that holds a sequence of whatever you want. So as an example, we can just say, you know, we'll make it variable. That's an array. Call it bar or we'll save our We'll call it just array, and it's going to be it's gonna hold 10 integers just like that. So this is the syntax that you would use to make an array, and then you can just simply go Ray Index zero, right. The first element in that ray will sign will sign it the value one and then array in next one. So the second element of the array is going to be two and so on, right? And then we can access the value of the vet array simply just through the same means like that. So when this problem must build that, so when this print statement executes, you know, the value stored at the first element of the array which has won this case, that's what's gonna get printed out. So I'm sure you've probably seen this before. If not, um, I hope this is pretty easy to understand. You know, raise. Like I said, just a sequence of imagers. It could be strings. Whatever data type you want, it just allows you to kind of store list of things in sequence. Um, one thing to know. One thing to note, though, is that a raise, you know, to instead she ate array like this or to make one, you have to include a length right. In this case, we have made an array that holds 10 integers, and you cannot resize in a raid just like you can't do that. And Java, you can't do it and see you cannot do and go either, however, go offers another feature called a Slice, which behaves and for all intense purposes is basically an array with a few subtle key differences. So before we get to that, one more thing I will say with a raise is You know, this is kind of the Mawr explicit way of making a rain, assigning assigning values to it's different in the season. What not the shorthand way of doing it is simply to say, array Colin equals and with the same kind of set up an image array that holds 10 elements. And we can just say 12345 some like that. So this will make an array that's 10 inches long. The 1st 5 numbers will be 12345 and the rest of after will be L zero, right just shorthand way of doing it now. Going back to slices a slice is essentially a view onto in array What does that mean? So, um, just demonstrated to an example. So we'll make a variable called slice right, And this is how you set it up. I'll explain this in tax in a moment, right? So slices variable, and it's going to like I said, behave just like an array and it's going to hold the 1st 3 elements of this variable array . So you basically think of this as an array itself. To some extent, that's just gonna hold the values. 123 right. And then this guy is essentially kind of the same thing. But I have 12345 and then 00000 like that. So that's how it's gonna look under the hood. And so I think you can kind of see what I mean when you say a slice is a view on to an array like this slice, for example, gives you a view of the 1st 3 elements of this array. You can think of it that way. Now, one thing to all skewed mine is a slice is has a pointer right to an array, basically knows the address that holds the values of the underlying array. Right? Which is this guy right here. And so anything that means anything that you change in the slice in terms of changing the values that it holds, it will also change those same values in a rate in the rate. So as an example, if I said slice zero equals 10 right now, slice is gonna be 10 23 and array is also gonna be 10 234500000 Right. So by changing the first element of this slice, I have also changed the first element of the rape and vice versa. If I change something in the array, if that number is also included in the slice and that number is going to get changed as well. So keep that in mind. You know, if you don't want to, um, change something in both the right and the slice. You know, you might wanna have to I just think a bit differently and I'll show you what I mean by that in a second. So if you don't want to have an existing array and a slice of the same time, right, cause if you change one, you change the other right typically do. And in most use cases that I've seen, um, on the job is you know, I'll just make an empty slice, right? And I'll just deal with that without the actual ray that's under under the hood. And so do that. I can simply say slice equals or a colon equals, um, empty brackets into and then empty curly brackets like that. So what this will do is it will technically build an array underneath the hood that I don't I don't actually have access to like I did in the previous example, and it will just make it of length. Zero have nothing in it, and then it will return a slice or a view onto that array. And that's what I'm dealing with here, right? And the reason why I prefer to deal with slices in this sense without actually making array and then making a slice on top of that and then dealing with a slice. I do it this way typically, because slices, unlike a raise, can be resized right. You can use the built in append function like this, and if I want to add, you know, 12345 right. This is it. That's, you know, this is going to do exactly how it sounds. It's going to take this empty slice and add the elements. 12345 into it. Right. And it's a simple is that you can't do this with an array necessarily. So there are a lot more intricacies and complexities that go into slices and the kinds of things you can do with them. Um, I'm not gonna go into that right here. I just wanted to cover the differences between a slice and array how they're connected. Um, what I typically use on the day to day basis in my job as a soft engineer, I have yet to use an actual array where I've defined, um, a length, for example. I typically just deal with slices, makes it much easier, um, and all that. So if you want to really dive into, um, you know the intricacies of slices in a raise, I will link somewhere in that is, in the description of this course, a go tutorial that you can look through. And it has some more detail and things like that where you can do your own independent research up to you. Um, so that slices. And then let's see the last thing I wanted to cover those two more things I want to cover so real quickly with slices. One neat way you can generate over the values of a slice and do things with them. Is there is this built in range keyword and go. So let me actually bring that back really fast. So, like you that here. So, I mean, I have a slice that holds 12345 Let's say I want to reiterate over that slice and put them out. I can just do a simple for loop, and you just have to simply fast like this. All right? So you know that you've seen four lips before? A little bit different than that. We have this range cured in here. And all this is doing is we're making two variables. I and I is going to be the index numbers going to be the value at that index, and then we're just printing them out. So in this loop for starts, I zero right, So we're gonna go into slice, right, get the first the value that stored at index zero, the first element, which is one. And they would put those out in front zero, and we'll put out one. And then the I value, which is the index becomes too. Excuse me. Becomes one, which is the second value in slice pulled out, which is the value, too. And we print those out and so on someone Now, you can also do it the more, um, old fashioned way of just saying for you know, I equals zero I. Unless then there's this lend function which will give you the length of the slice or an array. I left the length of these slice I less our I plus plus right. And then you can do, you know, perhaps. And then you can just print out slice bracket I like that, or actually make things parallel would be like this. Right? So you can totally do this as well. This is perfectly valid. Ghost in tax. This is perfectly valid. Ghost in tax. Um, but, you know, typically, if there is a more convenient, easy way to do something, I definitely recommend you do it that way. Um, so that's the range keyword. I just want to cover really quick. Pretty nice little handy feature. Last thing I wanted to cover in this video is maps, which you may have seen before. It's a very common data structure, just allows you to store key value pairing. So let's say, you know, I just want to map string keywords to integer values, right? So to make a map and go, the more explicit way do it is, you know, bar, we'll just call it M. And it's gonna be a map that maps strings to integers. That's how you would set this up and before you can actually go in and starts putting stuff in there, right? You know, you may have seen Syntex like this before. It's pretty straightforward. You just simply fast. All right, So this is how you would put things into the map. We're basically saying I want you to map the word one to the value, the integer one. Then map the word to to the integer two and so on. Right Before you can do this, though, you have to actually in Stan. She ate this variable this map through the make fun built in make function that's offered and go, So you would do just m equals make map, which is string. Tune it right. So you have to make sure you call this function in order to actually start putting values into it. There is a shorthand way of doing this. You can simply just do and Cohen equals make map string to it. Right. So this is a shorthand. But regardless, you have to make sure you call this make function, otherwise you're gonna get some heirs. And then, as I said, this is how you store values in the map. And then to get values out, just like an array, um, Except, you know, using keywords instead of just teenagers to get indexes. You know, we just do something like this, right? So this is gonna pull out the value that's associated with the word one, which happens to be the integer one, and we're gonna put out that integer very simple. And there's also a built in delete function. Right. So you wanted Teoh, um You see how this works? Yes. So we just do em. And then I said to right, so this is going to this function is going to just remove that pairing altogether. Um, that's pretty nifty. And then one more thing I want to show you before I wrap this video up is you know, if you wanted to check that a certain key key value pairing was inside a map, you can do something like this. Um, explain this in Texas has won a second. Um, i'll make about example here. So what this is doing is actually you could have an actual variable name right here, so I'll set this up in that case just for the sake of this example. So what this is saying is I want you to go check to see if the key three right, the actual war three is in the map, which is not. And if it's if it is in there than it will take out the value Assoc with that key, and it will put it in bow and it will set okay to true, but we know that three is not in the map. We have put it there yet, So how will just be new and ok will be set to false right? So you know, if you just want to check that something is in the map and you don't care about what the value is or what it's not. You can just kind of ignore the first argument by putting on underscore you still needed there so that the compiler knows that you want the map to output both the value and to her false, even though you're just ignoring the value itself. But you can do it this way, and then all you care about is okay, So you can just do you know if if, OK, you know, do something and quickly, you know, going back to if statements, you can do all this one line to which is really nifty, right? So I can just do if and just leave it at that colon. Okay, Boom. Right. So this will make that okay, variable on the fly. It will be set to false in this case because we don't have a key in the map. That's the word three. So OK will be false. And this if statement will not execute, but kind of cool that you can do this all one line very nice and neat, and that should cover everything that wanted to go over in this last part of go basics. I know this was definitely longer one a little more complex, little more in depth. Um, there's a lot I did not cover. So I just wanted to go over the high level stuff, exposed you till the different features and syntax and things like that. But you should this point b at least ready not to start running some go coding, getting yourself comfortable with it. So in the next video, we're gonna start going into interfaces and methods which is goes way of implementing some object or into design. But it is pretty different than Java, for example, which is kind of, you know, the king of object oriented design. So this is a bit different, how they implement it, but you will get used to it. And then in the final video will be going into concurrency and go routines, multi threading and more complex topics that, um, if you can leverage properly, will make your applications run extremely fast. So stay tuned for that. Got some exciting stuff coming up. And thank you for watching this video and I'll see you in the next one. Thanks 5. Methods and Interfaces: welcome back to the next video in this course. And now that we're done with go basics, which was basically just going over the syntax and some of the more basic features and data structures that the language offers now in this video and the next one is, well, we're gonna start diving into some more nuanced, little more complicated aspects of the language which do contain some go specific syntax and things. Um And so in this video, we're going to start talking about methods and interfaces which, if you have seen job before, for example, a lot of this should look conceptually very similar. You know, with Java, you have classes and interfaces and methods and things like that. Go has a lot of that, too. It's just they designed it in a little bit different ways, so it's gonna look differently in terms of the code. But conceptually speaking, it's all very similar, so kicking things off right now with methods, what is the method right? A method is simply a function just like any other function that you would see and go that has this special receiver argument on the front of it, which and you'll see this in a moment. Basically, a method is a function that you can tie to a certain data type right. Typically, a common example would be, ah, struck's. And so, if you have a variable, for example, that is of a type that is instructive some sort that you've created you can through dot notation call functions on that variable and that will that will elicit some kind of action , right? It's the best way I can demonstrate this is through an example, um, so similar to the previous videos, which can make a dog struck again. So we'll just do it globally. Type dog struck, but those curly brackets and you're the dog has got a name. Of course, it's got an age that's an imager and an owner Justin owner name, and we just make sure all this spacing looks nice and neat. So here's our dog struck that we've defined right. It's a data type that we have created ourselves and what we can do down below this main function or it doesn't matter where you put it necessarily, but we're going to make a function that is technically called a method, and it will basically be paired conceptually speaking with this dog data type and you'll see what I mean just in a second. So to make a method very similar set up you start with the funky word, and then you'll have some parentheses, and here you'll create some generic variable type that will be referenced with inside the function, and you'll see how this how this works more in a second. Then you have the actual data type itself, which is dog and then one. Let's call the function speak, for example, and that's it, and we'll just have it print out. You know, dogs typically say rough, right? And so that's what this function will do. So that's how you sent tactically create a method. I'll walk you through how this works in a second. I just want to get all the pieces set first. So going back to the main function, let's make a variable. Yeah, it's gonna be a dog struck essentially, so we'll just call it Dog to keep things you know, symmetrical and whatnot, and we'll do it the more shorthand way. Well said, The name is going to be Charlie Charlie. It's going to be the dog's gonna be three years old and the owner is going to be me. So, Scott, So in this main function, here we go. We've defined a dog variable that also is basically it's a dog struck right, has a couple attributes in it. And what not so similar to accessing the attributes, right? The name, the age, the owner through dot notation. Right, You can do dog dot And there you go age, for example. And that will that will fetch the age of this dog, which is three. Or, you know, you can use the equal sign too, a sign of a new value. So they're the same dot notation kind of syntax we can now call a function so we can call speak, right. And so what this will do is it will call this function speak, and it will print out rough to the terminal. And, you know, if you've seen Java before, you know, this should look pretty similar, right? You know, the the parallel to job would be This dog is an instance of a dog class and within that dog class, there are methods and you would invoke those methods you call those functions basically through this dot notation and it would print out in this case rough. So that's how methods work. And so going back to this receiver argument, this is kind of how you tile together. This is how you basically say this speak function is only gonna be able to be called when I have a dog variable of sorts and I can invoke it through this dot notation syntax, right. So this, Like I said, the speak function is basically tied to this dog struck right in that sense. Um, one thing to keep in mind, though, and this is where things are going to get a little bit tricky. Um, you can see here we are basically saying this function is tied to dog Struck's as as values , not pointers, right? And so the difference here is you know, I could leave it just like this. Oregon do that. And what this means is this speak function is now going to be tied to pointers to dog Struck's right. If remember from pointers, you know I can make one like this. Dog pointer equals ampersand dot Right, So now this dog pointer variable holds the address that is where the value all these attributes, for example, where the actual dog struck is stored somewhere in memory. That address gets stored in dog pointer. And with this new set up, I conveying Do dog pointer dot Speak right this star. Um, as I demonstrated earlier on with pointers, this star can actually be used in two ways. And perhaps I should have mentioned this, you know, in that video. But well, don't get into it now so the star can be used in two ways of this said So the first way, which is the way you've seen before, is I could do Star dog pointer, Um and then, you know, equals something. Bubble ball. That doesn't matter what is after this equal sign? The point is, this kind of statement basically says, You know, Dog Pointer is an address, it holds an address, and the star means go to that address, give me the value that stored there and then do something to it after the equals sign. In this case, right? The other way the star character can be used is to denote a variable as being a pointer. Right? So another example you might see is if I wanted to make a function is a typical function and we'll just call it function and it takes in a pointer data type, right? So instead of it taking in something like this, right, it's ever taking in a dog argument. That's just a type dog. Adding a star here basically means this argument is now a pointer to a dog struck right? So just recap the star could be used to denote the type of a variable. This means this dog input argument is a dog pointer. And in this context, the star basically means I want you to go to the address that stored at this point er and fetch whatever values at that address and then do something with it, right? And so the reason why I'm saying all this getting back to methods is here. We are now creating a method that is paired with a dog pointer, and the reason why this is useful is because if I were to take this start out right and it's just kind of clean things up here, make it more simple. In this case, you know, I made this dog structure. It's not a pointer right and I called dog not speak. This dog struck will essentially be copied behind the scenes. And so within this function will be dealing with that second copy that gets made in this D right here. This d will refer to that second copy that gets made. So if we were to change something in here, for example, for you to go d dot name equals Bob right within the context of this function, this d dog variable. Yeah, the name will get changed a bob, But this guy, this dog's trucked the name Charlie will not get changed because this whole thing gets copied. And then within the context of this function when this functions executing were only dealing with that copy. So after this function returns, if we were to, you know, maybe print out dog right after this function gets called the name still give me Charlie. It's not gonna be Bob right. And that's where things get confusing, right? You might wonder why that is just how, though, works. It's how see works. And so, if you wanted to actually change some attributes within a dog struck, for example, and let's actually change the name of this function to b'more Realistic. So we'll call it change name, and we'll have it taking an argument. Call new name String. And that's gonna be the new name. And so what we do here now is we add star Dogs. So now this method is going be tied to dog pointers A dog addresses, right? Basically, right. And the way this is gonna work So we have this initial set up, right? We make a dog, give it all the give the attributes values and now will make another, um, pointer, make a pointer cold, dark pointer, which is gonna be it's going to hold the address of dog, right? You've seen this before. And so now we can do dog pointer dot change name. And we're just passing the name that we want to be changed too. So let's say Bob right now, going back down to the change name function, right? Get rid of this for a second. Now, instead of this whole dog struck being duplicated, right, This this change name method is now being tied to dog pointers. Basically addresses. So the address of this dog struck gets stored in dock pointer and that address gets sent over basically to change name. So when we're dealing with this d variable this deep, the stock pointer this point is going to hold the address of this guy. It's not gonna be a duplicate dog struck as a value. It's just going to be the same exact address we can think of it to kind of be, um, to make things easy to understand, the address itself maybe gets duplicated and you're dealing with the address in change name . But even if you have two copies of the same address the same number, they're both gonna point to the same exact location of memory, right? It's only when you're duplicating the entire struck itself and you're copping all the attributes copping all the values, and you're making two separate dog entities. When you change one, you don't change the other. But if you have, you know, two copies of the same address, they're both gonna point to the same thing in memory. So you can think of it that way. And so, in this change name function, um, again, through the star kind of syntax, I could say star de right, which is basically saying whichever addresses stored in D. I want you to go fetch the value. That's their right. And I got princes around this, um, for this kind of set up dot and now I can access the name equals new name. So what this is going to do is it's gonna take the address in d is going to go to that address, get the value that stored there, the original dog struck. We're gonna pull the name out, and we're going to change to a new name. So in this case, um, going back up here to the main function, like when I call change name bypassing Bob and then I print out dog. Right? The original dog struck. Now the name will be changed. A Bob very key thing to keep in mind and understand Here with this whole concept and one, I guess I should mention one kind of shortcut with doing this is you don't need to make a dog pointer necessarily like this. You can simply do it this way, right? You do make your dog variable, and then with parentheses, ampersand dog, just dog. And there you go. So what this is saying is you know, I want you to get the address of dog, right? And with address. Then call the change name method, and then this method will execute will have the address of dog. And we'll change the name to Bob from Charlie to bomb. So I hope that makes sense. You know, this is more like I said, a more nuanced, complicated kind of topic. I want you to watch this video a couple times or, you know, like I said, I have linked the the go to toil that I found online and the tutorial that I have really kind of based this whole course around, I would definitely recommend going to that link as well. And walking yourself through some of the examples with this kind of, um, this kind of information And, you know, repetition is the key here. Go over multiple times, makes some examples yourself in whichever code editor that you you have and just kind of work through your understanding of this, right. Um and so I mean, there's one mawr kind of complexity on top of this, right? You can kind of see here. You know, I have print sees and ampersand pregnancies and a star and it's a little more complicated in terms of syntax. Um, go will allow you to just get rid of that. No prostheses, no star, no prints. Sees no ampersand because the compiler will know. Right? Let's look at this. Um, set up right here in the main function, and you say, dog dot change name, even though dog is not a pointer is just a dog struck value Because you have, um, created this change name method to deal with pointers. The compiler basically interpret this statement as princey ampersand closing front. See? And then there you go. That's how they could. Pilot will still interpret this line. You can still just as a programmer, be lazy and leave it out if you want. You know, it just makes things more confusing. Um, so I wouldn't get to that point yet until you fully understand how it is working. Once you fully understand what's going on, then you could be a little bit lazier. Same thing down here with the change name function. Um, since we're dealing with pointers here as we defined in the in the method header that compiler know that I mean, what this line you are basically meaning this. And so this is healthy. Compiler will interpret the statement, but you can certainly be lazy and just leave it at that and everything will still work this fine so that that's just a little added convenience. But as I said, I wouldn't start messing with that lazy syntax until you fully understand what's going on here. Um and so I think that's all I wanted to cover with methods. And now we're gonna get into interfaces. So interfaces are essentially just a set of methods signatures and, you know, conceptually speaking, they are beneficial in that they allow you to group A a series of different data types that are still similar in some way. Maybe they just, um, you know, in terms of their attributes or the kinds of things they're used for, they are similar, and so on interface allows you to group them together and allow you to refer to them all under, um or general kind of type. And so again, best way I can demonstrate this is through an example. So let me just kind of clean things up here. We'll do this with a clean slate, so to declare interface very similar to declaring ah, struck globally. Just do type And will this name it dog in her face. And so what you're you'll see here is that the interface is going to be the most general form. Most general type of the things that implement the interface and the things that implement the interface are going to be more specific types of dogs. So you'll see we're gonna make a golden retriever structure. We're going to make a poodle struck. These are both dogs, right? Dogs, the more generic label of these two things. But poodles are obviously different golden retrievers. They have different kinds of for textures, sizes, behaviors, things like that. And so you want to obviously keep those two entities separate, but it could be beneficial to refer to them both as just dogs. So you'll see how this all works in a second. So that's how you basically declare interface right here. And it has said these air basically sets of methods signatures, a method signature is basically just gonna be in the name of the method and the arguments, and it's returned type. So, for example, we'll just make a simple method signature speak as we've, um, as I have shown you before, and this method isn't taking any arguments as returning the arguments, but, you know, if it did, maybe takes an aunt of some sort and it returns a string, right? That's kind of how you would declare a method signature. But what to speak, function? No arguments needed, no return type needed. So that's it, right here. Here, is that this is the dog interface. And, you know, all dogs speak. To some extent, the sounds and noises they make are different, but they all speak, so you can kind of see, as we're going along, This interface is building the most general form of all the things that are going to implement the interface. So down beneath it, we're gonna make to struck's, um, one is gonna be golden retriever, right? Maybe instruct and you know it's gonna have a name, obviously. Ah, and age would ask you everything consistent. Two previous examples and owner just straying. Fix the space seeing. Okay, So here's our golden retriever struck, and the beneath that we're also gonna make a poodle instruct, right? And it's gonna have you seem attributes. Keep things a little bit more simple. Uh, int and then Boehner boom. So there we go. We have a golden retriever struck poodle struck. These are two different kinds of dogs, so you want to create separate entities for them, but ultimately there still dogs in the most general form, says Howard, slowly trying to tie these two things together. Now, in order for a type that you have created, typically there Struck's. You can do this with other data types as well. But, um, we're just dealing with Struck's in this example. In order to have your struck's implement this interface, you have to create methods for your struck's that the method has to be called Speak right. And that has to, I mean, if you defined this speak method to take in arguments and return something that methods you create for your golden retriever and poodle. Struck's also have to take in those same argument types, manager strings, whatever their specified to be and also return the same kind of data type. Maybe it's the energy may be too string whatever the case, so down here we're gonna create a speak method for golden retrievers and speak method for poodles, So we'll do funk. And since we're not going to be changing the actual attribute values for either the structure basically just printing something out, we don't necessarily need to use a pointer receiver argument. So just use for case of the golden retriever method. Um, de gr golden retriever for short. And it's gonna be golden retriever. This is the receiver argument, and it's gonna called speak. And there you go. And we're just going to have this print out, You know? I'm golden retriever, right? Obviously, dogs can't speak English, right? But for the sake of showing the differences, this is how we're going toe format. These speak methods. So this is our method for golden retrievers. Right? So you'll see the 2nd 1 when we make golden retriever struck or excuse me, had a golden retriever variable. You know, if you were to just call wherever we we've named the variable dot Speak, I'm a golden retriever, will get printed out, and the same thing will be true for poodles. Right? So we're gonna make another method for the poodle struck colleges. P for short, right? This is again the name that we're going to be This is the variable name that we're gonna be dealing with within the context of the function it's gonna take. Poodle also gonna be We're gonna name the the method Speak, and it's gonna print out. I'm, uh, poodle. Right. Okay, so at this point, right, the pool instruct and the golden retriever instruct have both implemented the dog interface . The dog interface says we need to have a speak method. And both the golden retriever and poodle Struck's both now have speak methods associated with them. That's great. Now, how does on this work? So going back to the main function, we're gonna make two variables. One's gonna be a golden retriever. One's gonna be a poodle. So we'll just golden the variable name and dio what does make a golden retriever struck in the shorthand way? Call it Charlie. And the age is going to be three. Owner is going to be me. So there's a golden retriever variable and then for poodle, Same kind of set up, uh, name. Call this poodle Bob. The age will be five years old and the owner will also be me. I own two dogs. Okay, So here are our two variables ones a golden retriever structure, ones a poodle struck. Um, and so, you know, if I were to do golden dot speak right, this would certainly work this airplane out. I'm a golden retriever. Likewise, If I were to do poodle that speak, this will print out I'm a poodle. Right. But the point of doing all this is, you know, to be able to refer to these two variables as dogs, not necessarily their mawr specific types. And I'll show you how this works their example. So let's say have another function, right. We'll just call it, um, test speak right. And this functions going to take in an argument that is simply of type dog, right? Doesn't take unnecessarily a golden retriever type or a poodle type. It takes in a dog type and more general form of poodles and golden retrievers, and we're going to do here. It's simply called dog, not speak right. That is what the function is going to do. So because golden retrievers and poodles, in terms of their struck's have both implemented the dog interface, we can no call test speak, um, and passed both them in like this. We'll call test. Speak with Golden and we'll call it test Speak. Um, with poodle Right now, In this case, with with this set up, we don't need to separate test speak functions. One that takes in a golden retriever type and one that takes in a poodle type. We can just have one test speak function that just takes an argument of type, dog and weaken. Used test speak. Um, in exactly this way, passing in a golden retriever, passing a poodle. Everything works everything compiles and runs just fine. Now, when these ah test speak function calls execute right in the context of test speak we're referring to are input argument as a more general type dog, right? So when we called dog dot speak under the hood, it will still know right In the case of this first function call, even though we're referring to this golden retriever as just a general dog when this function executes, it will still know that under the hood that this dog argument is actually a golden retriever, right? And so it will know to call this speak function as opposed to the poodle speak function, so it will still print out. I'm a golden retriever. Likewise, when this test speak, function executes and we pass in, the poodle struck in the context of dysfunction. Even though we're dealing with just a general dog type, it will still know that under the hood we're dealing with a poodle struck. And so, as a result, we called dog, not speak This poodle speak, function will run and we'll print out. I am a poodle, right? So this is, you know, a lengthy example, obviously. But it's a very common example that you'll see in regards to how interfaces are created, how they're used in the real world. Um, as I said, and as you can see here, you know, interfaces air just a great way of taking separate data types that are still related in some way and kind of grouping grouping them together under more general name. And then, in the case of you know, when you're making functions, I take it, you know, arguments in you can just specify the argument as just that general form the dog, for example, and then you anything that implements that dog interface, you can just pass it on into that function and everything will work just fine. So that's essentially what interfaces are. Um, there is obviously no more detail to this and what not? But, um, this is exactly what they are in a high level. And this is pretty much how I use interfaces in my day to day work when there's not a whole lot of other, more nuanced things that go may offer with interfaces that I have typically encountered. Yet this is pretty much the standard set up and procedure that I encounter most often as a software engineer doing go programming. So I hope that makes sense. And, you know, again, if you need to watch this video again, please do Look at that go tutorial. Walk yourself through the different examples. Like I said, the keys repetition here. So take your time working through this and, you know, as you work through it, you'll be upon your name and you understand all this in no time. So that concludes this more lengthy video on methods interfaces and in the final video Next , we're going to start going into, um, you know, multi threading how to use go routines, which will, you know, if you have multiple things going on your program and you want to make them happen. Kind of at the same time to speed things up. Go. Routines are gonna be your way to do that. And they'll make your applications run very, very quickly. So thanks for watching this video. And I'll see you in that final one. Um, and you're gonna learn a lot, so thanks. 6. Goroutines: Alrighty. Welcome back to the final video in this go crash course And this one in this last video, we're gonna be diving into go teens multi threading And how you can leverage that that future to allow your programs to do many things at once. Which will Tim leave drastically speed up the performance and efficiency, every program. And so, um, you know, with go creating threads using multi threading is actually quite easy and simple. I mean, if you don this kind of thing, we're seeing this kind of thing and see or even job to some extent, it could be pretty tricky to implement this correctly. You know, multiple threads makes everything synchronized and all that go very, very easy. So, you know, you still got be careful to some degree, but it's quite simple and clean. And, um, you know, as a result, this is one. My favorite languages to you is if I need to do some multi threading stuff. So, um, you know, if you're not familiar with the concept of threads multi threading in that kind of thing, I'll just give a brief review. Not gonna go too in depth, but, you know, a thread essentially is basically just a sequence of instructions that, as a whole can be scheduled to run on the CPU by the operating system. Right. So, you know, when you're writing your source code, right, you're go code and you compile that the compilers going to basically convert well, your source code into very specific step by step little instructions. And that whole set of instructions is what gets scheduled to run on the CPU by the operating system, right? If your program is single threaded than all those instructions that make up your entire application, that whole chunk, we'll get scheduled to run the CPU, right? But let's say you want to have multiple threads in your program so you have multiple sets of instructions that can independently be scheduled to run on the CPU by the operating system. Or I guess, you know, technically speaking, go over teens are scheduled trump by you know, the go run time. But that's besides the point. But multi threads, multi threading pro programs later have multiple separate chunks of instructions that could be run independently on the CPU, which is great, because if you want things to happen simultaneously, for example, you have to kind of procedures or tasks that you want to happen, and you want to have happen at same time. Make one threat for task 11 thread for task to and then leave it up to the go run timeto, you know, communicate with the operating system and say, Hey, I got two sets of instructions to tasks, you know, schedule them ideally at the same time on two different cores, or kind of swap them out frequently in the same court. Whatever it is, right. The point is, from the users experience the programmer and the user of the program, it will appear like these two tasks are happening at the same exact time, which is much more efficient and beneficial than having just one thread do task one first and then go to task to next and do it sequentially. It's always faster toe have those two things if they're independent enough to have them just occur at the same time, right? That will speed things up drastically. And so that's the whole concept of multi threading, right? Allows. You just have things going on simultaneously. So and go. Um, we're going. I'm gonna walk you through a pretty simple little example here. So we're gonna set up, um, two tasks that were that we want to run at the same time. So let's say you want one thread too. I constantly read from network traffic. Just pull network traffic, and maybe we're going to take that data and put it to a database or print it out, send it off to some other process whatever. So we're gonna encapsulate that task into a function would just call it Now listen, network, and we'll just have it be stuck in an infinite loop. And it's just going Teoh, um, breed network data, right? And then maybe do something with it. That's the set up for that first thread. The second thread. Let's say we just wanted to constantly read and write stuff to and from disk, right? So we'll just call this function, read right, and you also just have to be in an infinite loop, and it's just going to read and write to disk. And then we do some other stuff, right? So these two functions encapsulate those two specific independent tasks that we want to happen at the same time, and they're going back to the main function. This is where the main threat is going. Execute every application needs a main threat. This is how your program starts. And unless you unless you kick off other threads, The main thing is what's going to actually carry your program from start to finish, right? So back in the main function to create a new thread and have it execute one of these functions. It's as simple as writing. Go Listen Network and that's it. And then, for the other thread we right, go read right film. It's a simple is that this one line will create a whole new thread, a whole new set of instructions. And then those instructions will basically just be this function. And we'll just being this infinite loop, constantly reading network data and then doing something with it, right and same thing with this line will create a whole new thread with a set of instructions that just says, Hey, execute dysfunction, go in this infinite loop and constantly read and write data to and from disk right, and we also have the main threat as well, right? So we have three threads that we are that this program is comprised of. And as I said, each thread can independently be scheduled by the go run time whereby the operating system and they could be spread out into different cores or whatever. And like I said, from the users experience, it will seem like all these all three. These tasks are running at the same exact time, and that's just a brilliant concept. So, um, and then once these two threads have been created and they're both doing their indepent tasks than the main thread at that point, can be free to just continue on doing what needs to do next, right? He doesn't have to worry about listening to network traffic or reading and writing to disk . There's two other threads that are doing all that right, So that's how you know, on a high level you went one to think about breaking your program up into different threads . If it makes sense to do so, are you one different tasks happening at the same time? Another very cool feature of Go is this concept of channels and needs of the constructs that allow two threads or two threads basically to communicate with one another to send data to and from each other in a very simple, clean way. Um and so just kind of make a new example for that. So we just have the main thread communicating with some other thread that it creates back and forth like that. So we'll just make a do work function. This is the function is going to be executed by this. You can call the child thread that's going to be created by the main thread. And so I'll just leave it there for now. Get rid of these guys. So to create a channel, right, you can just store in a variable, for example. So what does make available called See? That's gonna be the channel itself. And we just have to use the make function, the built in make function and just say we want to make channel and have to specify what kind of data type is going to flow through that channel. Could be integers, strings, billions, whatever, well, to stoop managers. And that's it. This see very bullet is now a channel that can be used for by threats to send and receive imagers. Right, So that's how you make that. And then now that we have this weaken, edit this do work function, and it's gonna take in argument, the argument is going to be a channel, right? Simple as that. And so what was, you know, again, how to be stuck in an infinite loop? Maybe does some stuff, actually. Well, I'm not using different loop. I'm gonna just make it a simple for loop. So for, you know, I equals zero. I left. Then you let's say 100 I post. Plus, I could type and you little do some stuff. And then maybe at the end of it, we want to send something through the channel and keeping simple, we'll just send the value of I. And so this is how you do it? This is the syntax for it. And visually speaking is pretty easy to, um see what's going on here basically saying the value of I, which is an imager, and this arrow means send this value this imager through the channel, See, right, which is the input argument, right? That's it. So I gotta do to send data through a channel and then back in the main function where the main threat is executing. We'll make this guy be an infinite loop, and the main thing is going to be trying to pull data from the channel's gonna try and pull imagers from it. So to do that, we can just make a variable called Numb and Teoh pull data from a channel. Just use the arrow again. And there you go. Right. So kind of looking at it visually were saying and we were We are pulling imagers out of the channel and storing it in this numb variable, right? And then maybe we just want to print out the number Simple. Is that right? And, you know, maybe I'll just make it more clear here, do stuff and then said that send the energy on through, but yeah, this is this up, right? This is how you allow or how you can make two threads communicate to each other. One thread sending data through Channel one, threads receiving data. One thing to keep in mind, though, is in order for something to be successfully sent through a channel, the theory receiving thread and the sending threat both have to you ready to do that at the same time, right? The do work threatening is to be at this point, at the same time, the main threat is at this point and or not. Let's say the main threat is off doing something else that means the do work, thread the child thread. Even though it's at this point, it's ready. Descend because the main threads not ready. It's just going to stop and hang here and just wait and wait and wait until the main thread comes back around. Gets to this point. Now both roads are ready to go, and then the manager will get sent on through right, So keep that in mind. There is a work around with that you can basically, instead of making a channel like this, you can make it a buffer channel. So by adding an extra argument, here basically is saying that this channel can store up to 100 imagers before the receiving or sending thread can block right. So, for example, if the main threat is busy doing something else for a little while, and the do work threat is just constant trying to send injuries through the channel, it can keep doing that until the channel fills up with 100 imagers. Once the channels full the next time the do work thread tries to send something through, it's gonna block. And you have to wait until the main threat comes back around and starts pulling data out of that channel. Right. So you know that allows you to give get some kind of work around with that if you don't want one of threats to block, at least for a little bit a little bit of time. But, you know, eventually if one thought is not going to be ready very frequently, the channel's gonna fill up and you're gonna have something get blocked. But that's certainly an option. Not necessary for this example, though, um, so this set of certainly works, But you can see here in the main threat we have an infinite loop, right? You know, typically, at some point, we want our program to end right in Nice, clean way. So the way in, at least with this out the way we can have our program terminate cleanly and for the main threat to know that Hey, I don't need to listen and try to pull data from the channel anymore. Is the sending thread can close the channel, right? And you just do that through the clothes function and then the channel name, right. And we can do we can do this because you know this for Lupus finite, right? It's not gonna go on forever. Once I becomes 100 this full of is going to break out, and then this codes gonna execute. And so once we're done sending data through it, we can close the channel, which signifies that no more data can be sent through the channel. And you have to be careful when you do this. Because if you try to send data through a channel that has already closed the program, the whole program will crash right, Which is not something you want to happen. So it's always good practice toe. Have the sending thread be the one that closes the channel. The receiving threat can do it too. But like I said, if you there if it the receiving threat, close the channel and the sending three doesn't know about that and tries to send something through afterwards, your program is gonna crash. So, um, I strongly recommend doing it this way. So, you know, once this for That breaks out. We're done sending data. We can close the channel going back up to the main thread. The main function here. Well, we still don't least with the way it's currently written. We don't know that the channel has been closed, but it's very easy through some ghosts and tax using the range keyword, Um, to do this so we can basically just edit this full loop to say for numb basically in range . See the channel name right, see? And we can get rid of. That's because the number Abel's now kind of built in and there you go simple is that and what this will do is we had a four loop that's going to keep looping forever until the channel gets closed, right? The main threat is gonna constantly try to keep polling data point images from the Channel C putting the mountain and keep doing that until the do work thread has finishes full loop , it closes the channel. At that point, the main threat will recognize that in this four people break and then the main threat king continue executing more code or if that's it, then the program terminates the nice and cleanly, and that's all there is to it. Very simple, very easy. Like I said, go does this in a very beautiful way. Um And so then the last thing that I want to cover is select statements, and these were very useful. If you have multiple channels, right, And let's say each channel is being, um, written to buy multiple threads. And you have one thread trying to read from all those channels, right? If one of those channels isn't ready to be received from right, maybe the sender is busy doing something else. You don't want the receiver threat to just block, even though another channel might be ready to go, right? The centers there waiting for the receiver. But you don't want the receiver just to be blocked in something else. So, um, select statements are great for getting around this this issue so going to create the same kind of set up that we saw at the beginning of this video. So we're gonna make the, um, listen network function again and, you know, infinite loop. Um, it's gonna do some stuff, and then it's going to take in a channel and then at some point in the for loop. We're gonna try and write some data to its sense of data on through. No date is gonna be some variable, whatever it is. Maybe some, um, network data, and then we'll have another function. This is the read write function. It's been taking a channel as an argument. Infinite loop. Do some stuff, try and sense of data on through to that channel, right? That's a set up. Very simple. And then back in the main threat. Thank you for this. So we're gonna make two channels now. The first channel will call C one Channel one second channel channel will be called C two just like that, and then we'll kick off our threads and the listen, network threat is gonna have the first channel and the read write threat is gonna have access to the second channel. There you go. So if you want the main thread, for example, to constantly try and pull data from both these channels when we can have infinite loop again, right? And we could do something like, you know, data, um, equals and just pull data from C one, and maybe we'll do some stuff with that data, and we could say data equals on pulled data from sea to do some with that and then just repeat this process, right? Well, like I said, you know, this statement's gonna try to be executed first. But if the listen network threat is not ready to send data on through, the main threat is just going to get blocked. And it's gonna hang right here. Even though the read write thread may be ready at that time, he may be ready to send data through the channel, but the main threads busy just being blocked right here. It's never gonna get to this point until the list on network threat is ready to send that data on through. That's not efficient. We don't want to waste time in that way. Right? So to get around this issue, we can use a switch statement, which is gonna function very similarly to, um excuse me, not switch statement. My apologies. A select statement, a select statements going to function very similarly to a switch statement. Um, because they're both gonna use cases and they're set up in a very similar fashion. So, um, that way we can use a select statement, right. You can just sit the data variable like this, for example. And then we can have two cases, case one and try and pull data. Um, from the first channel, Ain't that right? And then we want to do some stuff with that do stuff. It will have a second case, and we'll just try to pull data from sea to, and then we'll try to do some stuff there. There were these guys, and there we go. So this is our solution, because what's gonna happen here is in this select statement, we're gonna try and pull data from the first Channel Channel, see one, right. But the list of network threats not ready to send data through, then no big deal. We're gonna go to the second case, we're going to try and pull data from Channel two, and that's not ready. Then we're just gonna go back to the top and then try and pull data from C one, and it's just gonna keep basically trying to do that until one of those threads is ready to send data on through. To my knowledge, it may the May 3rd may not actually costly loop through it this way. I think the implementation is Maura of, you know, under the hood, which ever cases just ready to be executed, that will just automatically execute. Um so you don't to worry necessarily about this infinite loop costly trying to check and maybe eating up some CPU time, but I'm not quite sure on those details. But regardless, that's the point of this is you will never have a situation where if you're trying to pull data from the first channel but the threat that's trying to send is not ready, you will not get stuck. At that point. You can automatically basically look at the other channel. Or if you have any more cases of more channels which ever one is ready to go first, that case will be executed, right? And if none of those cases are ready to go, you can add in a ah default statement and this will be executed whenever there is no case that is ready to go, right? You all your channels well, the senders are currently busy than the default statement will execute, right, And that should prove much cover. Everything I wanted to talk about with select statements, channels, go routines and all that. Um, so at this point, you have you have essentially reached the end of the course. So congratulations for achieving that. Um, in the final video, I'm just going to basically take a few minutes to talk about the course project wraps things up and then send join your way. So thanks again for watching this video. Congrats again for making it through all this go information. Um, I know it's a lot. So thanks again for watching this video and else you in that last video. Thanks. 7. Course Project: All right. So congratulations again. A logical putting this course with the exception of the course project, obviously. And that's why I wanted to discuss briefly here in this last little video. And the course project is I'm sure you could guess. Is essentially writing a small little go application? Um, I just designed to be a short, easy little exercise to get you up and going with the goal language. And the project is essentially what? An application that takes in a 16 digit credit card number from the command line right in this project is gonna require maybe a little bit of outside research, you know, how do I take in command line arguments, for example, I'll give you a hint. You might want to look at the flag package and go, but taking that 16 digit credit card number and then I want you to run this Lund's son. Lend some algorithm on it, right? Every credit card number has to pass this lunch. Some check to determine whether the card number is valid or invalid, right? And in the course project component of the course page, I've linked a little online tutorial that will tell you exactly how this works. It's pretty short and easy to understand. There's also some some Java and some C code that will actually show you how it's implemented in code. I wouldn't recommend you look at that stuff right away, obviously. But if you need a little bit more help, you know that code is there to kind of help you get started. But you're taking that 16 major credit card number. Run the lens, some check and then just print to the terminal. Whether this card number is valid or invalid, that's it, Right? Short little exercise shouldn't take you to be more than 60 minutes or so, but it would give you some good exposure to a lot of different go syntax and features, right writing functions, taking command line arguments, importing packages, four loops, all that stuff, right? So definitely something that I would recommend you do just get yourself started. And at this point, you know, you should feel pretty comfortable with the go laying programming language. And if you haven't already kind of work through that online tutorial that I've also linked in the, uh course description with death and recommend you work through that as well. Watching this course and doing that tutorial are both give you a very solid understanding of this go language. So, um, with that being said, thank you again for watching this course. I really appreciate it and hope to see you again soon. Thanks. Dick here.