Strictly speaking, Go is not a full object-oriented language. But having said that, it does have the capabilities of doing some OOP type things. Although it doesn’t have the concept of a class, you can still use
structs to create your own types and model real-world entities. This lesson will introduce the basics of
structs so that we can incorporate them into upcoming lessons.
1.Introduction3 lessons, 12:09
2.the Basics8 lessons, 1:15:15
3.Building Web Servers in Go4 lessons, 43:38
4.Conclusion1 lesson, 01:32
Odds are, if you've been doing any sort of software development in the last several years, you've probably become either familiar with or at least heard of concepts like object-oriented programming. Now while Go does have some support for object-oriented programming and some of its concepts, it does go about handling things a little bit differently. In the world of Go, we don't really have anything that's really called a class. Now there are structs, which I'm gonna talk to you about here for a few moments that do mimic some of the characteristics of classes but we don't really actually have a class per se. But let's take a look at a struct and see how we could use them as a class. So as you can see here, I have my normal skeleton of an application. And let's say I needed to create some sort of customized type that I wanna be able to use throughout my application to represent something in the real world that I'm modeling, so I can actually provide some value to a customer. Now, in this case, we're gonna keep it relatively simple. But let's come up with a simple concept. And we're gonna start talking about a point coordinate system. So within there, I need to represent different points at some sort of x and y coordinate. And how would I do something like that? Well, in the world of Go, as I mentioned before, we can use what's known as a struct. And a struct is really a way to encapsulate a group of fields. And then, if we wanna do things a little bit more object-oriented, like a class, we can add what's known as a method that will be accessible to that class or to this struct, but it's definitely done a little bit differently than you might be used to. So, let's start by creating a new type and this is going to be a point coordinate within our system. And the way that we're gonna do that is we're going to use the type keyword because we're ultimately creating a new type that we can use throughout our application. The actual name that we're gonna use for this is gonna be Point because I think that's descriptive enough to get our idea across. And then we need to specify that this is truly going to be a struct. And then within the curly brackets, we're gonna start to define fields, since a struct is really a way to encapsulate fields together that belong logically in the same location. Now with the Point, we're gonna keep this a fairly simple. We're gonna have two fields. We can have an X coordinate, which is gonna be an integer, and a Y coordinate which is gonna be an integer. So that's a fairly simple concept I think to wrap our head around. Now how do we actually use this struct after we have created it? Well, there's a couple different ways to create a new struct. Let's say that I want to create a center point within my coordinate system. Well, I'm gonna create a new center variable. And I'm going to initialize and set it to a point. Now there's a couple different ways that I can create a new point. I can use the new function. And then the new function takes in it a certain type. So I can pass in a point here. And then if I were to try to print out the result of this, I can try to print center. And I can run my application. As you can see here I get a pointer to a new point that has coordinates 0,0, so why did that happen and how did that happen? Well, the new function actually creates a new instance of whatever type was passed into it and then actually returns a pointer to it. So, at this point I actually had center as actually a pointer that is pointing to the coordinate system found in a point. And we're getting 0, 0 as our coordinates because 0 is the default value of an integer type. So that's pretty good. So if I wanted to do that, using the new keyword I can get some of those defaults, but what if I don't really wanna deal with a pointer in this case? What if that's a little bit too much work and I don't really need to do it that way? Well, there's another way that we can do this using a struct literal. So what I can do there is I can specify what type I want to create. And then use open and close curly bracket. This is kind of like the default of creating a struct. So if I run my application again, I get 0, 0 again but you're gonna see this is not a pointer this time. This is actually the value of the point which has default values X and Y. Now what if I wanted to give some default values other than 0 and 0 to my integers, how can I do that? Well, I can specify them explicitly within my struct literal here by specifying I wanna set X. And I want X to be equal to 1 and I want Y, to be equal to 2. So let's save that, we can run our application again. And there you can see, we have now initialized our X and Y fields to be other values. Now if I use this struct literal, I don't have to specify every field. I can actually just specify one if I would like, or any sort of subset as long as I explicitly call out which field that I'm actually setting. So if I were to run this again now, I should get 0, 2. So as you can see here, we can very easily and quickly create a struct that can represent a new type within our application that has some sort of logical association to the world that I'm trying to model. In this case we have a point coordinate system that I can start to build out. Now, I did allude a little bit earlier to the fact that it is possible to create a method that can be applied to a struct in almost a similar fashion to how you would maybe a class in other object-oriented languages. Although it is a little different, it is somewhat useful to be able to do this. Because what if I wanted to invert the coordinates of a point, and all I really wanted to do is say center.invert. But unfortunately, I don't have a function, I don't have a method that can do that right now, so I need to find a way to get that in there. Now I could write a separate function and call invert and pass center into it as a an argument, but that's a little bit uncomfortable to me and that doesn't really go into my workflow that I'm normally comfortable with. So what I'd like to do is create a method for Point. Now creating methods in Go is a little bit different than creating standard functions, but they're gonna look relatively similar. So we're going to specify the function keyword and then we're gonna have parameters here. Now we're not giving a name just yet. What I'm gonna supply as an argument to my function is actually going to be the type that I want to apply this method to. So in this case, I want to refer to a point, but I'm gonna give it a name p and it is going to be a pointer to a point. And then after the function argument list, that's when I'm going to give it a name. So I'm gonna call this invert, and then if I wanted this to actually return a value, I would specify the return value now just like I normally would in any other function. And then once I've done that, I am going to give the function body. So in this case, all I really wanna do, is I want to invert the values of X and Y within any point that's passed in, or with any point that I am using this method on. And if you saw the swap example earlier in this course, then you'll see that it's actually pretty simple to do that. I can specify p.X and p.Y is going to be equal to p.Y and p.X. So this is a very simple way to invert values within Go. So now I can save this. And I'm going to initialize my point to be at coordinates 5, 2 for X and Y. And then I want to use my invert function, so now I can say center.invert. And I can save this now. And if I try to print, I'm now gonna get, 2, 5. So as you can see, I've created a method. And although I've created a method outside of my struct, it's really associated with the struct because the argument list here or the argument itself is actually the type that I want to apply this to. So it's a little bit different of a workflow if you're not used to it or if your used to coming from other object-oriented languages. But it's really not that hard to get use to, especially if you enjoy using methods and creating a class-like structure, then this is definitely the route to go for you.