0% found this document useful (0 votes)
4 views

Introduction To Golang

Uploaded by

Siddharth Joshi
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Introduction To Golang

Uploaded by

Siddharth Joshi
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 13

Introduction

Go is a statically typed compiled language, often known as C for the 21st century.
Popular choice for server side applications.

The source code is compiled down to the machine code which means it will generally
outperform interpreted languages.
It is also known for its fast compile times.

Go mostly builds statically compiled binaries.

1. Statically Typed Language


This means we have to declare variable types explicitly or they have to be
inferred.
These types cannot change afterwards, at least without type conversion.
So in GO, the type of the variable must be specified.

2. Strongly Typed Language


Cannot just add a string and an integer together.

Due to these restrictions, compilers can do more thorough checking of the code
before compiling, leading to fewer bugs.

3. Compiled Language
Go comes with a compiler which translates your code to the machine level code.
It does this by producing binary files which can be run as standalone programs.

This can be relatively faster than the interpreted languages such as python.
Interpreted languages which use interpreters which translate the code line by line
adding more overhead which can make the execution relatively slower.

4. Built in Concurrency with Go Routines

5. Simplicity
Cross-Platform
Cross-platform means that software can run on multiple operating systems (OS) without
needing modification.

In the context of programming languages, this means you can write code once and
compile it to run on different platforms like Windows, macOS, and Linux.

Go (Golang) is designed to be cross-platform.


This means you can write Go code on one operating system and compile it to run on
multiple different operating systems and architectures.

Unlike Java's bytecode, which runs on any JVM, Go binaries are platform-specific.
This means a binary compiled for Windows won't run on Linux or macOS, and vice
versa.

With Go, it is Write once, Compile Anywhere.


Wheres in Java, you had like, Compile Once, Run Anywhere
Memory Management
Prerequisites of Memory
- What exactly is memory?
- Types of memory in Golang

Anything on the heap memory is managed by the Garbage Collector.


GC is very good, but it causes latency (For the whole program)

When to concern about memory management?


- If your program is not fast enough
- Benchmarks to prove it
- Show excessive heap allocations

Optimize for correctness first, not performance.

The Stack
A stack can have stack frames where each stack frame is dedicated to a function

Once the function is done executing, the stack frame associated with that function is
marked as invalid.
Golang doesn’t clean after itself in the stack.
The stackframe still exists, but it is somehow not used by the go.

As the new line of the code is executed (println), a new stack frame is created dedicated
to the function and then it is executed.

Stacks can be thought of as self-cleaning.


Any variables on the stack gets cleaned up as that space / frame gets reused.
Stack With Pointers

Passing pointers / references to things typically stays on the stack.

Returning Pointers

Here, we are returning a pointer from the function.


So the address of the variable in the stackframe of the func answer is passed to the
main function.
But now, since the control is back in the main function, the section of the func answer is
invalid.
And when we call the line println(*n/2), a new stackframe for it is created and the
space is reclaimed and we no longer have access to the stackframe of func answer,
but we’re still trying to dereference the pointer which exists in the old stackframe.

This is not what happens.

Instead, the compiler knows to allocate the variable x in the heap.

This is called escaping to the heap.

Sharing up (Returning pointers / references) typically escapes to the heap.


Sharing down (Passing pointers / references) typically stays on the stack.

At the end of the day, only the compiler knows whether the variable will be on stack or
on heap.

Whenever it can, the Go compilers will allocate variables that are local to a function in
that function’s stack frame.
However, if the compiler cannot prove that the variable is not referenced after the
function returns, then the compiler must allocate the variable on the garbage collected
heap to avoid dangling pointer errors.
Ask Compiler
When building the program, we can find out where the compiler stores all the variables,
whether in stack or heap.

go build -gcflags “-m”

When are values constructed on the Heap


1. When a value could possibly be referenced after the function that constructed the
value returns.
2. When the compiler determines that a value is too large to fit on the stack.
3. When the compiler doesn’t know the size of a value at compile time.
Mechanics of Arrays & Slices
An array is a contiguous block of memory.
Arrays in golang are not growable meaning that you cannot append more elements in
the existing array.

A slice, on the other hand, is a data structure describing a contiguous section of the
array.
A slice is not an array.
Rather, it describes a piece of the array.
Slice is represented in memory with three elements…
- Length
- Capacity
- Pointer to the first element in the backing array

With the syntax of


slice := []int{0, 1, 2, 3, 4, 5, 6}

Go’s compiler will automatically create the array backing this slice.
Consider this example

This is what happens internally with Golang’s compiler.

Different references of slices point to the same underlying backing array.


But the new slice has the length of 5 instead of 6 due to the function.

How Append Works


The append functionality always modifies the length field in the slice header.
May also modify the capacity and pointer field too.

When we create a slice with some initial values, the slice header will have the same
value and capacity.
0xc1030 is the address of the first element in the backing array
2 is the length and capacity.

Now, if we try to append a new element in this slice, there is not enough storage in the
backing array as shown in the diagram.
So, Go will allocate a new backing array twice the current capacity and copy the existing
elements to it.

As a result, the slice headers are modified to the new values.


The other elements in the array are set to 0 (Their default values).

The garbage collector will free the memory of the old array.
String, Bytes and Runes
Different Ways to Write Strings

Internals of String
String is basically a slice of byte.

The first field is the pointer to the first element in the underlying array of byte.
The Len field is the length of bytes.
This is the result for this code snippet.

The length returned is 9, but in fact the length of the string from a human’s perspective
is only 6.
This is because string is backed by an array of bytes internally.
And the emoji is represented in 4 bytes and the rest of the characters in 1 byte.

You might also like