Basics of Go

Numbers & Collections

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Basics of Go

Check out a free preview of the full Basics of Go course

The "Numbers & Collections" Lesson is part of the full, Basics of Go course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano explores the usage of global functions for converting between different number types in Go, and introduces collections such as arrays, slices, and maps. It is important to note that collections in Go are not objects and can be manipulated using global functions.


Transcript from the "Numbers & Collections" Lesson

>> Numbers, so if we have, for example, an integer, and we wanna make any operation with that number and use a float, so we have an integer and float, it's not gonna work. Compared with other languages such as C or JavaScript, we don't have here automatic conversion between Types.

So if you need to make a math operation over an integer and a float, we must send them to the same type before, floats or ints, up to you. For doing that, we have global functions with the same name of every type, for example, int, float 32. We parse something inside and it will give us the converted value.

That's not magic, not every conversion is possible. We cannot convert on a string with an with a name into a bool, so it's not gonna work with every type. Okay, we will see later in which conditions these will work. For strings, multi-line strings are available by default, but I'm not sure if you remember that we got an error when we tried to do that.

But it's kind of a linter that you can change, because now it's better to use the backtick for multiline strings. We will get there later anyway. Collections, we haven't mentioned collections yet, arrays. I'm not sure if you will like how the Type is being defined, but you use.

For arrays, we have arrays, slices, and maps, those are the kinds of collections we have. An array, if you're here, you probably know what it is. It's a collection of elements, it's a sequence of elements, a list of elements. But in Go, arrays have a fixed length. So if I create an array of five elements, that array will have five elements forever, I cannot add more.

I can create a new array, taking those five elements and adding one more but I cannot increase capacity of that array. And to use that, we use square brackets, the length, the capacity within the square brackets and the type. So in this case, here, we have an array of five integers, that's the type.

So when you declare the type, that's how it looks like. Then we have slices, that it looks like it's an array but with a dynamic length. So you can see we use the same square brackets without a number and then the type that we want inside. However, behind the slides, we have real arrays.

Actually, it's a slice of an array, okay? I know it's kind of weird for now, but let's say that when you create a slice and you add more elements to the slides dynamically, behind the scenes, we do have fixed length arrays, that's the idea and we are just seeing it's like a view.

We are seeing a partial view of that other array, okay, have that in mind for now. A map is a key value dictionary that typically we have on a lot of programming languages. The Type definition is kind of weird. I have to say that I don't like how you define the Type.

Let me show you this directly in the code. So remember, we don't have here a data package that is just a folder. I'm going to create another file collections.go. And because it's in the data folder, it must start with package data. And what if I wanna create the collection?

I wanna export that collection. If I wanna export that collection, they must contain the export keyword. Now, we just need to use title case. So for example, if I'm gonna create a variable, we use var, and then the name of the variable such as countries, capital C. And the type is going to be, for example, 10 countries and something like that.

What's the value of those countries? Nil, empty, so we have 10 countries with no content right now. Well, let me tell you something, we can create init functions. If you create init functions like this, you could create or you could execute code like that. We can also say sub 0 = 2.

So you will use indexes like that, Countries. Let's say, I don't even need to be in order. I can say that's sub 8, When init is going to be executed? Init is executed typically when you start your app. It doesn't matter in which package do you have them.

In fact, I can have another init here. Be careful, init is not main, different thing, okay? Init is just a function where you can initialize things when the app starts, and this is going to be really, really weird. Look at that. I can have more than one init functions with the same name, in the same package, in the same file and it works.

It's the only exception for repeating the same name, init. So that means that you can separate different blocks of things you wanna initialize by group, by type. So you open one init, another init, another init, they're going to be executed in definition order, okay? So I can just do fmt.Print(A and B) here.

And then if I execute my app, you will see AB60, that's the max speed. They should remove, and then Hello World. So you can see that A and B, I can use print line if you want to separate these from the rest. AB and Hello World, init goes first before main.

And I can add another init here that says, for example, fmt, format, Printlin("Counties saved") or something like that. And then you can see that, oops, what happened? What happened with this? I'm not seeing countries saved, I'm seeing A and B but not the rest. So what's going on here?

Well, the thing is that I'm using the data, but not yet this file. I'm not using this file yet. So I have set the countries, but I'm not using something from that file. So we will get there. So init is the only exception for, let's say, function overloading.

It's not really an overloading because I'm not changing arguments, but it's weird that you can have more than one init, okay? But that's one collection, that's the array. The slice works in a similar way. So you say, I have a slice, and you do this. The light of what?

So integers, and then you can add. I will show you how to add more in a minute, okay? And then we have a map. The map is key value, okay, key value. For example, I can say that I have, I don't know, codes and this is how you set up the type.

You say map, you open a square brackets, the type of the key within brackets, for example, integer and the type of the value that you will get for each key, I know a string. And is kind of weird because we use a type within brackets, which is kind of weird, so the map keyword is mandatory.

And then you say, types. It can be in the bool. For every number, you get the bool. We will use these collections later in some examples, okay? What else do we have in terms of collections? That's all. That's all, what about, for example, if you wanna get the length of the countries?

If you're coming from other languages, maybe you're expecting something like Countries.length, but we don't have objects here. This is not OOP, so that's not how things work. If you want to get the length of, in this case, the array, we have a global function called len from length, so then you can create a variable like quantity like that.

It's complaining because I'm not using quantity, but that's how you get the length of an array, len parenthesis and the collection. The same len function also works for strings and also other types. So based on the type that you seen as an argument, we'll actually act differently. Is that polymorphism?

It's a similar idea, at least, okay? So using the same function and based on the type is going to act differently, but it's not OOP. So it's more like an if somewhere asking for the type and making things differently, okay, sounds good. Okay, let's go back here for a second.

It's collections, as I mentioned, collections are not objects, nothing is an object, actually. So we use global functions to work with them, len, cap will give you capacity. That's useful for example for slices, because maybe you have two elements, but the capacity is large. Some examples here, and here you can see how can I use.

They look like code blocks, but it's just a constructor. You will see in a minute that we do have constructors to construct data types, and the constructor is also curly braces. Okay, so here, I'm creating a slice with Mary and John, and append will actually add one element to the array.

But actually, if you look at the code, it's not appending to names, it's actually reassigning names, so you are reassigning all the time. We will do some tests here. But actually, I don't have a slice. If I have a slice of two elements and I wanna add a new one, I'm actually creating a new slice with three.

And if I want to add another one, I'm creating a another slice. I'm not changing the same slice, right, I'm creating a new one all the time. And maps, they look like B. For example, well-known ports, it's a map, the key is a string. For example, in this case, the protocol and the value is an integer in this case, the port number, key value.

That looks like JSON, okay, kind of. It's actually JSON compatible.

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