Golang Data Structures Chapter 5.1
Index of GoLang Resources
- How to install Go? | Chapter 1 |
- Creating Your First GoLang Project |Chapter 2 |
- GoLang Language Fundamentals | Chapter 3 |
- Control Flow in GoLang | Chapter 4 |
- GoLang Data Structures | Chapter 5.1 |
- GoLang Data Structures | Chapter 5.2 |
- GoLang Concurrency | Chapter 6 |
- Error Handling in GoLang | Chapter 7 |
- Common Utilities in GoLang Project | Chapter 8 |
- GoLang Database/SQL | Chapter 9 |
- GO with GORM | Chapter 10 |
As we have seen how control flow and functions work in Chapter – 4 of our Golang tutorial, let’s have a look at major Golang Data Structures.
Array –
Well, almost every programmer knows what is an array. But let’s revisit the concept one more time –
Basically, the array is a number of elements of the same type stored in sequential order. We use arrays to store fixed no. of more elements which are really a good data structure.
We need to follow the below syntax to create an array :
Data Structures: Slice
Slice is the same as an array but it has a variable length so we don’t need to specify the length to it. It will grow whenever it exceeds its size. Like an array, slice also has index and length but its length can be changed.
-
Slice also has continuous segments of memory locations
-
The default value of uninitialized slice is nil
-
Slices does not store the data. It just provides a reference to an array
-
As we change the elements of slice, it will modify corresponding elements of that array
Syntax for slice creation is:
The only difference between slice and array is that there is no need to specify length while creating slice.
Here, slice of type float64 elements will be created with length 0 & capacity 0
This will create slice of underlying string array having size for 5 elements
Length→ No. of elements present
Capacity→ Total Size
The length and capacity of slice can be obtained by using len(slice), cap(slice)
Below is another example –
Normally we switch ON value of a variable but Golang allows you to switch ON type also.
Here in above program, you can see how length and capacity increas when it exceeds size limits. The capacity will be doubled when size exceeds the capacity.
If we think that our slice might grow, we can set capacity which is larger than length. This gives slice room to grow without creating new array every time our slice grows.
We also can create slice inside another slices like –
Example:
-
Once you declare an array with its size you are not allowed to change it.
-
If you try to insert more elements than array size, the compiler will give you an error.
-
By default array size is 0 (zero)
-
Array index starts from 0th index
-
We can set value directly to array at particular index array_name[index]=value
-
The inbuilt len returns the length of an array
Go provides a convenient way of storing elements.
You can do slicing on a string because the string is slice of bytes.
Remember → String is made up of runes (Uni Code). A rune is Unicode UTF Codepoint (for ‘A’-65’, ‘a-97’). A Unicode codepoint is 1 to 4 bytes.
So, strings are made up of runes, runes are made up of bytes,so strings are made up of bytes. A string is a bunch of bytes, a slice of bytes.
You can access slice elements by using range in for loop.
There are built-in functions to calculate length by using len(slice), capacity by using cap(slice), append one slice to another by using append(slice) and copy(slice) to copy one slice to other.
We can create slice in three ways:
-
Using var
-
Shorthand Notation
-
make( )
Here in above program, you can see how length and capacity increas when it exceeds size limits. The capacity will be doubled when size exceeds the capacity.
If we think that our slice might grow, we can set capacity which is larger than length. This gives slice room to grow without creating new array every time our slice grows.
We also can create slice inside another slices like –
Data Structures: Map
One of the most important and useful data structure in computer science is HashTable. Golang provides map data structure which implements hashtable. An unique key value pair like dictionary is used to lookup values based on the key.
Map is represented by keyword map having key type in [ ]and value types.
The default value of map is nil as it is reference type like pointer or slice and for nil key and value pairs are 0.
This includes unordered pairs. Maps are like literals but unique keys are required.
Here map name is dictionary having key-value pairs of string & int type.
The values are accessed using key values. The maps can be created by using make( ) also which is more effective to use.
The make() creates a hash data structure and return map value pointed by key. Go provides familiar syntax to work with map data structure.
The functions provided are len(map) and delete(mapName,key)
Comma OK idiom: If we are looking for value related to particular key then map returns two values: one value if found and value that indicates success or failure(not present). We call this comma OK idiom.
Comma OK idiom: If we are looking for value related to particular key then map returns two values: one value if found and value that indicates success or failure(not present). We call this comma OK idiom.
Range: Range is used to iterate over the slice and map along with for loop. When range is used with slice it returns two values- 1st one is index and 2nd one is copy of the element at that index.
Data Structure – Struct
-
Encapsulation → state [“fields”] behavior [“methods”] export / unexported
-
Reusability → Inheritance [“Embedded Types”]
-
Polymorphism → Interfaces
-
Overriding → Promotion
Golang doesn’t have keyword ‘Class’ but it has ‘struct’ which is contains named collection of fields/properties. Struct is also there in ‘C’ language.
Struct→
-
user-defined type
-
we declare the type
-
the type has fields
-
the type can also have “tags”
-
the type has an underlying type
-
in this case, underlying type is struct
-
we declare variables of the type
-
we initialize those variables
-
initialize with specific value or with default values.
In some object-oriented languages methods are composed within struct or class
But in Golang, they are ‘associated’ with struct.
A struct is defined by using type and struct keyword along with a meaningful name
Here type defines new type followed by name of struct and then struct keyword
Example –
We can create instance of our struct Mobile in many ways like
This will create a local variable mob and sets the default value to its fields (0 for int, “ ” for string, 0.0 for float)
It will allocate memory to all fields by setting default values and returning a pointer to it (*Mobile). More often we need to give values to each of the fields. We can do this in two ways:
Fields →
We need to define meaningful name & type for fields or properties. We can initialize fields with its value or can keep blank so it will use default value.
We have to access the struct fields with “. (dot)” only.
Accessibility and Visibility of struct and variables
There is no concept like the public, private, protected for the visibility purpose in Golang. As Golang is simple, if the first letter of the struct name or variable name is capital then it is visible outside that package.
Methods
Go supports methods to define-struct.
In between the keyword func and functionName, we’ve added the receiver. “Receiver” is like parameter-it has its name and type, and by creating this we have to call the function using “.” operator.
You cannot declare a method with a receiver whose type is defined in another package.
Sample Code –
Methods having pointer receivers can modify the value to which the receiver points.
We can define method on any type defined in struct as well as from same package but you cannot define method on type from another package.
Type Aliasing –
We can create aliases for the type that you want to use.
We can also attach methods to the types. See the “time” package having type Duration – https://golang.org/pkg/time/#Duration
Embedded Types –
A struct’s properties/fields usually represent has-a relationship like inheritance. Suppose we have a struct person.
And now if we want to create a new struct. We can do like this –
So, Go supports relationship like this by using embedded type, also known as anonymous fields.
Here, we are using type Person by embedding into Mobile. Now to access the struct Person fields we can use type name.
Promotion –
Embedding is the composition, not inheritance, but Go supports something called “promotion” where the fields and methods of the embedded type become available to the embedding type.
This is something like inheritance but actually not inheritance.
Go automatically handles conversion between values and pointers for method calls. You may want to use a pointer receiver type to avoid copying method calls.
Struct Pointer
We can use struct pointer to access struct fields –
Well, we have covered some of the major Data Structures for Golang in this chapter. In Part II of this chapter, we will dive deeper and explore some more Golang Data Structures. Make sure you check it out!