Check out a free preview of the full Polyglot Programming: TypeScript, Go, & Rust course

The "Submarine Go Solution" Lesson is part of the full, Polyglot Programming: TypeScript, Go, & Rust course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen walks through translating the TypeScript solution into the Go version of the solution to the submarine navigation problem. A student's question regarding if underscore is a reserved variable name for the Go compiler to skip if it's not used.


Transcript from the "Submarine Go Solution" Lesson

>> I hope everybody's ready to jump back in this. Hopefully this all made sense I just got done explaining that I do want to make sure that the problems that we're doing are not complex in nature, they're actually simple. They're more fun to understand how to parse strings in these various languages than it is to solve some specific math trick like the Chinese remainder theorem, which did catch me for quite some time on advent of code last year.

But so let's do this exact same problem, but let's do it and go. All right, so this is we're gonna get kind of crazy here. So I'm gonna go back to my projects folder and I'm gonna make a directory called go. Why not? Right that seems pretty good we're going to go learn.

Okay, so I'm gonna go go mod init, you always have to do this, this is just you have to give it a name and the names are always URLs. So there we go the primeagen, we're just gonna call it aoc, there we go. So you're gonna do the exact same thing if you're going to Go go mod init, here you go do this thing.

It's gonna create a new Go module and then of course, I'm gonna do get init because I like to have proper fuzzy finding with ignoring, say node modules and other things. There we go and so now I'm gonna open up that beautiful editor known as Vim. So if you guys are using VS Code, you're probably still clicking your way there, but I'm just kidding, it's okay.

In Go, a standard project kind of setup is that you have CMD command as where you put your main files in, and then you have PKG package where you put kind of like your library files. There's also internal and other things but in general, that's kind of the two main things you're going to see in a lot of packages.

There's a few other packages that have specific meanings, but we're just going to rely on that. So I'm gonna create a directory called CMD, inside there, I'll create another directory called p1 because any directory can only have at max one main file, right? And so we'll create p1 and in here you can call it whatever you want to call it, I just call it main.go just out of just whatever.

So the first thing you put at the top of all Go files of course is what package does it belong to, when it belongs to the main package you're telling the compiler that this file will also contain the entry point into your program. And of course, the entry point is main, pretty simple.

And so I'll give you a quick second so me personally, I'm gonna hop back to this thing and I'm gonna grab this nice little function right here, and I'm gonna hop back and I'm gonna get this thing in here. All right, so however you guys need to do that just get the input into this program.

And I'm going to translate this from TypeScript into Go which is actually pretty easy. The first thing you do is just take off the tion on func so now it's just func and then of course remove the semicolon or remove the colon because you don't use that as identifying a return value.

And there we go, we've now just written successful go and pretty easily, right? Go and TypeScript are actually rather similar in most cases, shockingly similar. Now it might even feel a little bit shocking that it was that easy, but it is that easy. All right so, unfortunately Go does not really favor the functional approach to things and when it comes to string processing, I've always felt like that was kind of a nice paradigm to use.

So we're gonna use the non fun paradigm we're going like this, parts equals string so there's this library called strings which has a bunch of Helper functions, to be able to do things. So if you have an LSP active, when you use it, it should auto import it up here if you don't have it you need to make sure it imports strings.

I would definitely make sure you get used to having those things auto imported it's just way easier. We're gonna call the method Split remember capital letters identify things that are exported so this string module exports something called Split. And I'm going to split my input getInput via the new line all right actually we can call this thing lines all right look how beautiful that is.

So now Go, one nice thing about Go is that it kind of has the liner built into the LSP I'm not using lines therefore I cannot even compile this project right if you're not using all your variables it does not compile, right? It just wants to make sure you don't make stupid mistakes.

Go is inherently written for the new graduate that's even part of the design goal that I forget the person's name who created it. That was one of his design goals was to make this as easy of a language as possible while maintaining the most performance as possible. So let's do a little for, so whenever you do, by the way the underscore denotes this is a variable, but I will not use it.

So I'm gonna do a little quick for loop. And of course the colon equals means this is a new variable, whereas the equal is assigning, just so you know, I'm gonna do there you go so this is a quick for loop I'm gonna range over the lines. And this right here is the index, right?

And this right here is the thing. So there we go we have those two things. And so now I need to do something with those two things. So much like the previous one, where we did this like parse line let's build the same function, but let's do it in Go.

So I'm gonna jump back and we're gonna go like this func parseLine we're gonna take a line string and what we need to return out is going to be something now we can't do this. Now obviously, this would be great I would like to do that we can do an array of two, that is an option but let's just use a struct, right?

Let's use some structs, let's kind of get used to more kind of GUIism type thing. So we're gonna go like this, type, we'll call it Point I'm not sure if it's really a point it's kind of more of technically like a vector, but we're just gonna call it whatever right a tuple, it doesn't really matter.

Type Point struct and we're gonna have an x that is an int and a y that is an int. Now notice you don't put any commas you don't put in any semi colons so what you do and of course, let's return that point from this. All right, so now let's start parsing the line, I'm gonna just copy this line, bring it up here, and I'm gonna call it parts.

And I'm gonna split of course the line on whitespace, just like we did in our previous program on our other version. We're just simply splitting now each line by the whitespace so now we're gonna have ford up down on one side, and we're gonna have a number on the other side.

So let's first, let's get the amount out, let's get that number out, right? So I'm gonna go like this amount equals again you can use strcon which is another one of these libraries out there that is just provided to you, this will convert strings into some other set of types.

So I'm gonna press yes on this thing, which obviously means that I'm importing it. If you don't have it imported it breaks, make sure you have that thing auto imported and I'm gonna like this Ato, now this is a kind of a call back to an old function.

I think it stands for ASCII to integer or ArrayBuffer to integer, I cannot remember exactly what it stands for but it's gonna effectively take in a string and convert it into a number. So I'm gonna go like this parts 1 like this but you're gonna see something right right away what is the error it says you cannot initialize one variable with two values, what does that mean?

Well if we jump to the definition it returns an int and an error. All right we're already into the error land with girl so let's do this so I'm gonna add the word err, what should we do if we hit an err? Well, for the sake of this program, we should never hit an err ever.

So I'm just gonna just ruin the program right here this thing doesn't work out. So I'm gonna do my standard little if err does not equal nil, I'm gonna import something called log. When you do log you can add a fatal and I'm just going to be like this should never ever happen I'm going to just destroy this program immediately right this should just never happen and that's just a fact of life.

All right awesome so now we have this beautiful amount int, we have our parts, which still has part zero which has the direction. So now we just do the old, amount equals oops, double equals doesn't have a strong of equal signs, forward, my goodness do the exact same thing return point.

Go actually, will auto format when I hit a nil, it'll auto format it to look a little differently but x will be like do I use amount? Parts 0 that's silly of me, amount y of course is 0 correct, does that makes sense, Go also make you put what's called commas at the end, it's considered an actual parsing error.

It's one of the things that makes Go so fast that compiling is that it enforces a super strict syntax. And so that just means that the language is way less complex. If you always, every there's no checking to see, is there an extra comma at the end? No, there's always a comma at the end we always expect at the end right?

So that's part of the reason what makes Go really fun is that it just parses super fast so I'm gonna copy that whole thing do a little else if and change this to up right if it's up let's move this thing down, call this thing x, call that thing y and put a minus sign.

Good so now we're dealing the upper portion and of course, we can copy it again, align it, and this would be the downforce, right? Does that all make sense? I'll give you guys a moment to look at this I think the problem is fairly straightforward it's just more learning the syntax.

Yeah we got a question.
>> Is underscore reserved variable name for which the Go compiler skips checking if it is declared not used?
>> Yes, it identifies to the compiler that you will not be using this. And so that's kind of how, it's just like Rust, Rust also gives you the same semantics.

Rust just says start anything with an underscore and we know it will not be a warning for you. We already know that you're planning on using it, it's just or you're not planning on using it. It doesn't matter, we just won't consider it Go is just a little bit more strict about these things, in Rust you get a warning during build time in Go you get a hard error you may not proceed.

And so of course the underscore is built for that. All right so long as we've done everything mostly correct I should be able to do the following I'll go like this position equals a point. Now this is called a list initializer this can be very painful and very good at the exact same time let me give you a fun error that took me about 30 minutes to figure out what was going wrong.

All right if we go up to our definition and I go like that and I have I think I may put this in my presentation I may not so we'll find out I have x equals 0 have I put that myself semicolon there you don't need it y.

If I were to do x, y in other languages, you might go the x gets assigned to the x, the y gets assigned to the y, wrong it's a list initializer. It's gonna go in order of the properties that are in the struct, this is just like a hard gotcha be very careful about this.

So in this example, if x was 1 and y was 0, my actual definition would have y as 1 and x is 0 so careful, careful, careful. Just really, I don't know why but I don't understand that one but it is what it is, so let's just deal with it.

So there we go we have our position we're gonna create our amount we're gonna go up here and what do we call this thing parseLine? ParseLine and let's just parse in our line this thing is going to return back out a point we can see right there it's a point and of course pos x plus equals amount x copy it replace x with y, boom, you got it, we're done.

Now long as we've done everything correctly, we should be able to do a little format print. We can use log printing we already have log in here now we're like mixing log versus format. Don't worry about it at this point in your Go development life you don't you know, you don't need to know the finer points of logging.

Though I'm positive someone out there will be like, don't worry about it. All right point and so we can use this fun little operator called the +v this will kind of give us a more debugged print of our values. So if I've done this correctly, we should see ourselves with a 15 and a 10.

So I'm going to go go run, and I gotta go to the location, command p1 main.go. And there we go 15, 10 just like our previous one obviously I didn't multiply them together to get 150 but as you can see, not too bad, right? That was a shockingly some simple language here, I'm gonna zoom it out a little bit.

Kind of verbose a little bit long, but at the exact same time, like nothing in here happened, that I think anyone was shocked about if you've never even seen Go until this moment it's a pretty straightforward language. And that's one thing I've just grown to really appreciate about the language is that you get speed without the complexity

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now