Sunteți pe pagina 1din 165

Chapter 1: What is Golang?

Go Programming Language
The Go Programming Language, also commonly referred to as Golang, is a general-purpose
programming language, developed by a team at Google. The Go language was conceived in
September 2007 by Robert Griesemer, Rob Pike, and Ken Thompson at Google. Go first
appeared in November 2009, and the first version of the language was released in December
2012. The official web site of the Go project is http://golang.org/. Go has its own elegance and
programming idioms that make the language productive and fun to code. Go also provides a
comprehensive standard library. The standard library provides all the core packages
programmers need to build real-world, web and network-based programs. Go is a statically
typed, natively compiled, garbage-collected, concurrent programming language that belongs
primarily to the C family of languages in terms of basic syntax.

The Go Programming Language is an open source project that is distributed under a BSD-style
license to make programmers more productive. Go is expressive, concise, clean, and efficient
programming language. Go compiles quickly to machine code yet has the convenience of
garbage collection and the power of run-time reflection. It's a faster, statically typed, compiled
language that feels like a dynamically typed, interpreted language.

Go is a compiled language, and like many languages, it makes heavy use of the command line.
Go is both the name of the programming language and the name for the toolset used to build and
interact with Go programs.

Go is a statically typed programming language. What that means is the compiler always wants to
know what the type is for every value in the program. When the compiler knows the type
information ahead of time, it can help to make sure that the program is working with values in a
safe way. This helps to reduce potential memory corruption and bugs, and provides the compiler
the opportunity to produce more perform-ant code. Go struct lets you create your own types by
combining one or more types, including both built-in and user-defined types. Structs are the only
way to create concrete user-defined types in Go. When you create your own types using struct, it
is important to understand that Go does not provide support for inheritance in its type system, but
it favors composition of types that lets you create larger types by combining smaller types. The
design philosophy of Go is to create larger components by combining smaller and modular
components. If you are a pragmatic programmer, you will appreciate the design philosophy of
Go that favors composition over inheritance because of its practical benefits. The inheritance of
types sometimes introduces practical challenges with regard to maintainability.

In the last decade, computer hardware has evolved to having many CPU cores and more power.
Nowadays we heavily leverage cloud platforms for building and running applications where
servers on the cloud have more power. Although modern computers and virtual machine
instances on the cloud have more power and many CPU cores, we still can't leverage the power
of modern computers using most of the existing programming languages and tools. Concurrency
in Go is the ability for functions to run independent of each other. Its concurrency mechanisms
make it easy to write programs that get the most out of multi core and networked machines,
while its novel type system enables flexible and modular program construction. When a function
is created as a goroutine, it's treated as an independent unit of work that gets scheduled and then
executed on an available logical processor. Goroutines are created by calling the Go statement
followed by the function or method that you want to run as an autonomous activity. The Go run-
time scheduler is a sophisticated piece of software that manages all the goroutines that are
created and need processor time. The scheduler sits on top of the operating system, binding
operating system's threads to logical processors which, in turn, execute goroutines. The scheduler
controls everything related to which goroutines are running on which logical processors at any
given time.

Chapter 2: Variables

Golang Variables

A variable is a name that represents a data stored in the computer's memory. Here're some
important things to know about Golang variables:

 Golang is statically typed language, which means that when variables are declared, they either
explicitly or implicitly assigned a type even before your program runs.
 Golang requires that every variable you declare inside main() get used somewhere in your
program.

 You can assign new values to existing variables, but they need to be values of the same type.

 A variable declared within brace brackets {}, the opening curly brace { introduces a new scope
that ends with a closing brace }.

Declaring (Creating) Variables

The keyword var is used for declaring variables followed by the desired name and the type of
value the variable will hold.

You can declare a variable without assigning the value, and assign the value later.

package main

import "fmt"

func main() {
var i int
var s string
i = 10
s = "Canada"

fmt.Println(i)
fmt.Println(s)
}

After the execution of the statements above, the variable i will hold the value 10 and the variable
s will hold the value Canada.

Declaration and Initialization

The assignment of a value occurred inline with the initialization of the variable. It is equally
valid to declare a variable and assign a value to it later.

package main

import "fmt"

func main() {
var i int = 10
var s string = "Canada"

fmt.Println(i)
fmt.Println(s)
}

The integer literal 10 is assigned to the variable i and the string literal Canada is assigned to the
variable s.

Variable Declaration Omit Types

You can omit the variable type from the declaration, when you are assigning a value to a variable
at the time of declaration. The type of the value assigned to the variable will be used as the type
of that variable.

package main

import (
"fmt"
"reflect"
)

func main() {
var i = 10
var s = "Canada"
fmt.Println(reflect.TypeOf(i))
fmt.Println(reflect.TypeOf(s))
}

Short Variable Declaration

The := short variable assignment operator indicates that short variable declaration is being used.
There is no need to use the var keyword or declare the variable type.

package main

import (
"fmt"
"reflect"
)

func main() {
name := "John Doe"
fmt.Println(reflect.TypeOf(name))
}

The John Doe string literal will be assigned to name.

Declare Multiple Variables

Golang allows you to assign values to multiple variables in one line.

package main

import (
"fmt"
)

func main() {
var fname, lname string = "John", "Doe"
m, n, o := 1, 2, 3
item, price := "Mobile", 2000

fmt.Println(fname + lname)
fmt.Println(m + n + o)
fmt.Println(item, "-", price)
}
Scope of Variables Defined by Brace Brackets

Golang uses lexical scoping based on code blocks to determine the scope of variables. Inner
block can access its outer block defined variables, but outer block cannot access inner block
defined variables.

package main

import (
"fmt"
)

var s = "Japan"

func main() {
fmt.Println(s)
x := true

if x {
y := 1
if x != false {
fmt.Println(s)
fmt.Println(x)
fmt.Println(y)
}
}
fmt.Println(x)
}
Note that short variable declaration is allowed only for declaring local variables, variables declared
within the function. When you declare variables outside the function, you must do so using the var
keyword.

Naming Conventions for Golang Variables

These are the following rules for naming a Golang variable:

 A name must begin with a letter, and can have any number of additional letters and numbers.
 A variable name cannot start with a number.

 A variable name cannot contain spaces.

 If the name of a variable begins with a lower-case letter, it can only be accessed within the
current package this is considered as unexported variables.

 If the name of a variable begins with a capital letter, it can be accessed from packages outside
the current package one this is considered as exported variables.

 If a name consists of multiple words, each word after the first should be capitalized like this:
empName, EmpAddress, etc.
 Variable names are case-sensitive (car, Car and CAR are three different variables).

Zero Values

If you declare a variable without assigning it a value, Golang will automatically bind a default
value (or a zero-value) to the variable.

package main

import "fmt"

func main() {
var quantity float32
fmt.Println(quantity)

var price int16


fmt.Println(price)

var product string


fmt.Println(product)

var inStock bool


fmt.Println(inStock)
}

When the above code is compiled and executed, it produces the following result −

0
0

false

Variable Declaration Block

Variables declaration can be grouped together into blocks for greater readability and code quality.

package main

import "fmt"

var (
product = "Mobile"
quantity = 50
price = 50.50
inStock = true
)

func main() {
fmt.Println(quantity)
fmt.Println(price)
fmt.Println(product)
fmt.Println(inStock)
}
Chapter 3: constants

Golang Constants

A constant is a name or an identifier for a fixed value. The value of a variable can vary, but the
value of a constant must remain constant.

Declaring (Creating) Constants

The keyword const is used for declaring constants followed by the desired name and the type of
value the constant will hold. You must assign a value at the time of the constant declaration, you
can't assign a value later as with variables.

package main

import "fmt"

const PRODUCT string = "Canada"


const PRICE = 500

func main() {
fmt.Println(PRODUCT)
fmt.Println(PRICE)
}

You can also omit the type at the time the constant is declared. The type of the value assigned to
the constant will be used as the type of that variable.

Multilple Constants Declaration Block

Constants declaration can to be grouped together into blocks for greater readability and code
quality.

package main

import "fmt"

const (
PRODUCT = "Mobile"
QUANTITY = 50
PRICE = 50.50
STOCK = true
)

func main() {
fmt.Println(QUANTITY)
fmt.Println(PRICE)
fmt.Println(PRODUCT)
fmt.Println(STOCK)
}

Naming Conventions for Golang Constants

Name of constants must follow the same rules as variable names, which means a valid constant
name must starts with a letter or underscore, followed by any number of letters, numbers or
underscores.
By convention, constant names are usually written in uppercase letters. This is for their easy
identification and differentiation from variables in the source code.

You will learn more about Data Types, in our Golang Data Types tutorial.

Chapter 4: data types

Data Type
Go is a statically typed programming language. This means that variables always have a specific type and
that type cannot change. The keyword var is used for declaring variables of a particular data type. Here is
the syntax for declaring variables:

var name type = expression

On the left we use the var keyword to declare a variable and then assign a value to it. We can declare
mutiple variables of the same type in a single statement as shown here:

var fname,lname string

Multiple variables of the same type can also be declared on a single line: var x, y int makes x and y both
int variables. You can also make use of parallel assignment: a, b := 20, 16 If you are using an initializer
expression for declaring variables, you can omit the type using short variable declaration as shown here:

country, state := "Germany", "Berlin"

We use the operator : = for declaring and initializing variables with short variable declaration. When you
declare variables with this method, you can't specify the type because the type is determined by the
initializer expression.
package main

import "fmt"

//Global variable declaration


var (m int
n int)

func main(){
var x int = 1 // Integer Data Type
var y int // Integer Data Type
fmt.Println(x)
fmt.Println(y)

var a,b,c = 5.25,25.25,14.15 // Multiple float32 variable declaration


fmt.Println(a,b,c)

city:="Berlin" // String variable declaration


Country:="Germany" // Variable names are case sensitive
fmt.Println(city)
fmt.Println(Country) // Variable names are case sensitive

food,drink,price:="Pizza","Pepsi",125 // Multiple type of variable


declaration in same line
fmt.Println(food,drink,price)
m,n=1,2
fmt.Println(m,n)
}

Chapter 5: convert types

Converting and Checking Types


Package strconv implements conversions to and from string representations of basic data types.
Atoi is equivalent to ParseInt(s, 10, 0), converted to type int. ParseInt interprets a string s in the
given base (0, 2 to 36) and bit size (0 to 64) and returns the corresponding value i.

package main

import "strconv"

func main() {
strVar := "100"
intVar, _ := strconv.Atoi(strVar)

strVar1 := "-52541"
intVar1, _ := strconv.ParseInt(strVar1, 10, 32)

strVar2 := "101010101010101010"
intVar2, _ := strconv.ParseInt(strVar2, 10, 64)
}

How to Convert string to float type in Go?

ParseFloat converts the string s to a floating-point number with the precision specified by
bitSize: 32 for float32, or 64 for float64. When bitSize=32, the result still has type float64, but it
will be convertible to float32 without changing its value.

package main

import (
"fmt"
"strconv"
)

func main() {
s := "3.1415926535"
f, _ := strconv.ParseFloat(s, 8)
fmt.Printf("%T, %v\n", f, f)

s1 := "-3.141"
f1, _ := strconv.ParseFloat(s1, 8)
fmt.Printf("%T, %v\n", f1, f1)

s2 := "-3.141"
f2, _ := strconv.ParseFloat(s2, 32)
fmt.Printf("%T, %v\n", f2, f2)
}
float64, 3.1415926535
float64, -3.141
float64, -3.1410000324249268

How to convert String to Boolean Data Type Conversion in Go?

ParseBool returns the boolean value represented by the string. It accepts 1, t, T, TRUE, true,
True, 0, f, F, FALSE, false, False. Any other value returns an error.

package main

import (
"fmt"
"strconv"
)

func main() {
s1 := "true"
b1, _ := strconv.ParseBool(s1)
fmt.Printf("%T, %v\n", b1, b1)

s2 := "t"
b2, _ := strconv.ParseBool(s2)
fmt.Printf("%T, %v\n", b2, b2)

s3 := "0"
b3, _ := strconv.ParseBool(s3)
fmt.Printf("%T, %v\n", b3, b3)

s4 := "F"
b4, _ := strconv.ParseBool(s4)
fmt.Printf("%T, %v\n", b4, b4)
}
bool, true
bool, true
bool, false
bool, false

How to convert Boolean Type to String in Go?

FormatBool function used to convert Boolean variable into String.

package main

import (
"fmt"
"reflect"
"strconv"
)

func main() {
var b bool = true
fmt.Println(reflect.TypeOf(b))

var s string = strconv.FormatBool(true)


fmt.Println(reflect.TypeOf(s))
}
bool
string

How to Convert Float to String type in Go?

FormatFloat converts the floating-point number f to a string s.

package main

import (
"fmt"
"reflect"
"strconv"
)

func main() {
var f float64 = 3.1415926535
fmt.Println(reflect.TypeOf(f))
fmt.Println(f)

var s string = strconv.FormatFloat(f, 'E', -1, 32)


fmt.Println(reflect.TypeOf(s))
fmt.Println(s)
}
float64
3.1415926535
string
3.1415927E+00

Convert Integer Type to String Type

FormatInt converts the Integer number i to a String s.

package main

import (
"fmt"
"reflect"
"strconv"
)

func main() {
var i int64 = -654
fmt.Println(reflect.TypeOf(i))
fmt.Println(i)

var s string = strconv.FormatInt(i, 10)


fmt.Println(reflect.TypeOf(s))
fmt.Println(s)
}
int64
-654
string
-654

Convert Int data type to Int16 Int32 Int64


package main

import (
"fmt"
"reflect"
)

func main() {
var i int = 10
fmt.Println(reflect.TypeOf(i))

i16 := int16(i)
fmt.Println(reflect.TypeOf(i16))
i32 := int32(i)
fmt.Println(reflect.TypeOf(i32))

i64 := int64(i)
fmt.Println(reflect.TypeOf(i64))
}
int
int16
int32
int64

Convert Float32 to Float64 and Float64 to Float32


package main

import (
"fmt"
"reflect"
)

func main() {
var f32 float32 = 10.6556
fmt.Println(reflect.TypeOf(f32))

f64 := float64(f32)
fmt.Println(reflect.TypeOf(f64))

f64 = 1097.655698798798
fmt.Println(f64)

f32 = float32(f64)
fmt.Println(f32)
}
float32
float64
1097.655698798798
1097.6556

Converting Int data type to Float in Go


package main

import (
"fmt"
"reflect"
)

func main() {
var f32 float32 = 10.6556
fmt.Println(reflect.TypeOf(f32))

i32 := int32(f32)
fmt.Println(reflect.TypeOf(i32))
fmt.Println(i32)
f64 := float64(i32)
fmt.Println(reflect.TypeOf(f64))
}
float32
int32
10
float64

chapter 6: operators

Golang Operators

An operator is a symbol that tells the compiler to perform certain actions. The following lists
describe the different operators used in Golang.

 Arithmetic Operators
 Assignment Operators

 Comparison Operators

 Logical Operators

 Bitwise Operators

Arithmetic Operators

The arithmetic operators are used to perform common arithmetical operations, such as addition,
subtraction, multiplication etc.

Here's a complete list of Golang's arithmetic operators:

Operator Description Example Result

+ Addition x+y Sum of x and y

- Subtraction x-y Subtracts one value from another

* Multiplication x * y Multiplies two values

/ Division x/y Quotient of x and y

% Modulus x%y Remainder of x divided by y


Operator Description Example Result

++ Increment x++ Increases the value of a variable by 1

-- Decrement x-- Decreases the value of a variable by 1

The following example will show you these arithmetic operators in action:

package main

import "fmt"

func main() {
var x, y = 35, 7

fmt.Printf("x + y = %d\n", x+y)


fmt.Printf("x - y = %d\n", x-y)
fmt.Printf("x * y = %d\n", x*y)
fmt.Printf("x / y = %d\n", x/y)
fmt.Printf("x mod y = %d\n", x%y)

x++
fmt.Printf("x++ = %d\n", x)

y--
fmt.Printf("y-- = %d\n", y)
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


x + y = 42
x - y = 28
x * y = 245
x / y = 5
x mod y = 0
x++ = 36
y-- = 6

Assignment Operators

The assignment operators are used to assign values to variables

Assignment Description Example

x=y Assign x=y

x += y Add and assign x=x+y

x -= y Subtract and assign x=x-y


Assignment Description Example

x *= y Multiply and assign x=x*y

x /= y Divide and assign quotient x = x / y

x %= y Divide and assign modulus x = x % y

The following example will show you these assignment operators in action:

package main

import "fmt"

func main() {
var x, y = 15, 25
x = y
fmt.Println("= ", x)

x = 15
x += y
fmt.Println("+=", x)

x = 50
x -= y
fmt.Println("-=", x)

x = 2
x *= y
fmt.Println("*=", x)

x = 100
x /= y
fmt.Println("/=", x)

x = 40
x %= y
fmt.Println("%=", x)
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


= 25
+= 40
-= 25
*= 50
/= 4
%= 15
Comparison Operators

Comparison operators are used to compare two values.

Operator Name Example Result

== Equal x == y True if x is equal to y

!= Not equal x != y True if x is not equal to y

< Less than x<y True if x is less than y

<= Less than or equal to x <= y True if x is less than or equal to y

> Greater than x>y True if x is greater than y

>= Greater than or equal to x >= y True if x is greater than or equal to y

The following example will show you these comparison operators in action:

package main

import "fmt"

func main() {
var x, y = 15, 25

fmt.Println(x == y)
fmt.Println(x != y)
fmt.Println(x < y)
fmt.Println(x <= y)
fmt.Println(x > y)
fmt.Println(x >= y)
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


false
true
true
true
false
false

Logical Operators

Logical operators are used to determine the logic between variables or values.
Operator Name Description Example

&& Logical And Returns true if both statements are true x < y && x > z

|| Logical Or Returns true if one of the statements is true x < y || x > z

! Logical Not Reverse the result, returns false if the result is true !(x == y && x > z)

The following example will show you these logical operators in action:

package main

import "fmt"

func main() {
var x, y, z = 10, 20, 30

fmt.Println(x < y && x > z)


fmt.Println(x < y || x > z)
fmt.Println(!(x == y && x > z))
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


false
true
true

Bitwise Operators

Bitwise operators are used to compare (binary) numbers.

Operator Name Description

& AND Sets each bit to 1 if both bits are 1

| OR Sets each bit to 1 if one of two bits is 1

^ XOR Sets each bit to 1 if only one of two bits is 1

Zero fill left


<< Shift left by pushing zeros in from the right and let the leftmost bits fall off
shift

Signed right Shift right by pushing copies of the leftmost bit in from the left, and let the
>>
shift rightmost bits fall off

The following example will show you these bitwise operators in action:
package main

import "fmt"

func main() {
var x uint = 9 //0000 1001
var y uint = 65 //0100 0001
var z uint

z = x & y
fmt.Println("x & y =", z)

z = x | y
fmt.Println("x | y =", z)

z = x ^ y
fmt.Println("x ^ y =", z)

z = x << 1
fmt.Println("x << 1 =", z)

z = x >> 1
fmt.Println("x >> 1 =", z)
}

You should see the following output when you run the above program −

C:\Golang\examples>go run main.go


x & y = 1
x | y = 73
x ^ y = 72
x << 1 = 18
x >> 1 = 4

chapter 7: if else

Golang If...Else...Else If Statements


In this tutorial you'll learn how to write decision-making conditional statements used to perform
different actions in Golang.

Golang Conditional Statements

Like most programming languages, Golang borrows several of its control flow syntax from the
C-family of languages. In Golang we have the following conditional statements:
 The if statement - executes some code if one condition is true
 The if...else statement - executes some code if a condition is true and another code if that
condition is false

 The if...else if....else statement - executes different codes for more than two conditions

 The switch...case statement - selects one of many blocks of code to be executed

We will explore each of these statements in the coming sections.

Golang - if Statement

The if statement is used to execute a block of code only if the specified condition evaluates to
true.

Syntax

if condition {
// code to be executed if condition is true
}

The example below will output "Japan" if the X is true:

package main

import (
"fmt"
)

func main() {
var s = "Japan"
x := true
if x {
fmt.Println(s)
}
}

Golang - if...else Statement

The if....else statement allows you to execute one block of code if the specified condition is
evaluates to true and another block of code if it is evaluates to false.

Syntax

if condition {
// code to be executed if condition is true
} else {
// code to be executed if condition is false
}

The example below will output "Japan" if the X is 100:

package main

import (
"fmt"
)

func main() {
x := 100

if x == 100 {
fmt.Println("Japan")
} else {
fmt.Println("Canada")
}
}

Golang - if...else if...else Statement

The if...else if...else statement allows to combine multiple if...else statements.

Syntax

if condition-1 {
// code to be executed if condition-1 is true
} else if condition-2 {
// code to be executed if condition-2 is true
} else {
// code to be executed if both condition1 and condition2 are false
}

The example below will output "Japan" if the X is 100:

package main

import (
"fmt"
)

func main() {
x := 100

if x == 50 {
fmt.Println("Germany")
} else if x == 100 {
fmt.Println("Japan")
} else {
fmt.Println("Canada")
}
}

Golang - if statement initialization

The if statement supports a composite syntax where the tested expression is preceded by an
initialization statement.

Syntax

if var declaration; condition {


// code to be executed if condition is true
}

The example below will output "Germany" if the X is 100:

package main

import (
"fmt"
)

func main() {
if x := 100; x == 100 {
fmt.Println("Germany")
}
}

You will learn about Golang switch-case statement in the next chapter.

Chapter 8: if else

Golang If...Else...Else If Statements


In this tutorial you'll learn how to write decision-making conditional statements used to perform
different actions in Golang.
Golang Conditional Statements

Like most programming languages, Golang borrows several of its control flow syntax from the
C-family of languages. In Golang we have the following conditional statements:

 The if statement - executes some code if one condition is true


 The if...else statement - executes some code if a condition is true and another code if that
condition is false

 The if...else if....else statement - executes different codes for more than two conditions

 The switch...case statement - selects one of many blocks of code to be executed

We will explore each of these statements in the coming sections.

Golang - if Statement

The if statement is used to execute a block of code only if the specified condition evaluates to
true.

Syntax

if condition {
// code to be executed if condition is true
}

The example below will output "Japan" if the X is true:

package main

import (
"fmt"
)

func main() {
var s = "Japan"
x := true
if x {
fmt.Println(s)
}
}
Golang - if...else Statement

The if....else statement allows you to execute one block of code if the specified condition is
evaluates to true and another block of code if it is evaluates to false.

Syntax

if condition {
// code to be executed if condition is true
} else {
// code to be executed if condition is false
}

The example below will output "Japan" if the X is 100:

package main

import (
"fmt"
)

func main() {
x := 100

if x == 100 {
fmt.Println("Japan")
} else {
fmt.Println("Canada")
}
}

Golang - if...else if...else Statement

The if...else if...else statement allows to combine multiple if...else statements.

Syntax

if condition-1 {
// code to be executed if condition-1 is true
} else if condition-2 {
// code to be executed if condition-2 is true
} else {
// code to be executed if both condition1 and condition2 are false
}

The example below will output "Japan" if the X is 100:


package main

import (
"fmt"
)

func main() {
x := 100

if x == 50 {
fmt.Println("Germany")
} else if x == 100 {
fmt.Println("Japan")
} else {
fmt.Println("Canada")
}
}

Golang - if statement initialization

The if statement supports a composite syntax where the tested expression is preceded by an
initialization statement.

Syntax

if var declaration; condition {


// code to be executed if condition is true
}

The example below will output "Germany" if the X is 100:

package main

import (
"fmt"
)

func main() {
if x := 100; x == 100 {
fmt.Println("Germany")
}
}

You will learn about Golang switch-case statement in the next chapter.

Chapter 9 switch case


Golang Switch…Case Statements
In this tutorial you will learn how to use the switch-case statement to perform different actions
based on different conditions in Golang.

Golang also supports a switch statement similar to that found in other languages such as, Php or
Java. Switch statements are an alternative way to express lengthy if else comparisons into more
readable code based on the state of a variable.

Golang - switch Statement

The switch statement is used to select one of many blocks of code to be executed.

Consider the following example, which display a different message for particular day.

package main

import (
"fmt"
"time"
)

func main() {
today := time.Now()

switch today.Day() {
case 5:
fmt.Println("Today is 5th. Clean your house.")
case 10:
fmt.Println("Today is 10th. Buy some wine.")
case 15:
fmt.Println("Today is 15th. Visit a doctor.")
case 25:
fmt.Println("Today is 25th. Buy some food.")
case 31:
fmt.Println("Party tonight.")
default:
fmt.Println("No information available for that day.")
}
}

The default statement is used if no match is found.


Golang - switch multiple cases Statement

The switch with multiple case line statement is used to select common block of code for many
similar cases.

package main

import (
"fmt"
"time"
)

func main() {
today := time.Now()
var t int = today.Day()

switch t {
case 5, 10, 15:
fmt.Println("Clean your house.")
case 25, 26, 27:
fmt.Println("Buy some food.")
case 31:
fmt.Println("Party tonight.")
default:
fmt.Println("No information available for that day.")
}
}

Golang - switch fallthrough case Statement

The fallthrough keyword used to force the execution flow to fall through the successive case
block.

package main

import (
"fmt"
"time"
)

func main() {
today := time.Now()

switch today.Day() {
case 5:
fmt.Println("Clean your house.")
fallthrough
case 10:
fmt.Println("Buy some wine.")
fallthrough
case 15:
fmt.Println("Visit a doctor.")
fallthrough
case 25:
fmt.Println("Buy some food.")
fallthrough
case 31:
fmt.Println("Party tonight.")
default:
fmt.Println("No information available for that day.")
}
}

Below would be the output on 10th day of month.

C:\golang\dns>go run example.go


Buy some wine.
Visit a doctor.
Buy some food.
Party tonight.

Golang - swith conditional cases Statement

The case statement can also used with conditional operators.

package main

import (
"fmt"
"time"
)

func main() {
today := time.Now()

switch {
case today.Day() < 5:
fmt.Println("Clean your house.")
case today.Day() <= 10:
fmt.Println("Buy some wine.")
case today.Day() > 15:
fmt.Println("Visit a doctor.")
case today.Day() == 25:
fmt.Println("Buy some food.")
default:
fmt.Println("No information available for that day.")
}
}

Golang - switch initializer Statement

The switch keyword may be immediately followed by a simple initialization statement where
variables, local to the switch code block, may be declared and initialized.
package main

import (
"fmt"
"time"
)

func main() {
switch today := time.Now(); {
case today.Day() < 5:
fmt.Println("Clean your house.")
case today.Day() <= 10:
fmt.Println("Buy some wine.")
case today.Day() > 15:
fmt.Println("Visit a doctor.")
case today.Day() == 25:
fmt.Println("Buy some food.")
default:
fmt.Println("No information available for that day.")
}
}

Chapter 10: for loop

Golang For Loops


In this tutorial you will learn how to repeat a block of code execution using loops in Golang.

A for loop is used for iterating over a sequence (that is either a slice, an array, a map, or a string.

As a language related to the C-family, Golang also supports for loop style control structures.

Golang has no while loop because the for loop serves the same purpose when used with a single
condition.

Golang - traditional for Statement

The for loop is used when you know in advance how many times the script should run.

Consider the following example, display the numbers from 1 to 10 in three different ways.

package main

import "fmt"

func main() {
k := 1
for ; k <= 10; k++ {
fmt.Println(k)
}

k = 1
for k <= 10 {
fmt.Println(k)
k++
}

for k := 1; ; k++ {
fmt.Println(k)
if k == 10 {
break
}
}
}

Golang - for range Statement

The for statement supports one additional form that uses the keyword range to iterate over an
expression that evaluates to an array, slice, map, string, or channel

package main

import "fmt"

func main() {

// Example 1
strDict := map[string]string{"Japan": "Tokyo", "China": "Beijing",
"Canada": "Ottawa"}
for index, element := range strDict {
fmt.Println("Index :", index, " Element :", element)
}

// Example 2
for key := range strDict {
fmt.Println(key)
}

// Example 3
for _, value := range strDict {
fmt.Println(value)
}
}

Golang - range loop over string

The for loop iterate over each character of string.


Consider the following example, display "Hello" five times.

package main

import "fmt"

func main() {
for range "Hello" {
fmt.Println("Hello")
}
}

Golang - Infinite loop

The for loop runs infinite times unless until we can't break.

Consider the following example, display "Hello" several times.

package main

import "fmt"

func main() {
i := 5
for {
fmt.Println("Hello")
if i == 10 {
break
}
i++
}
}

Chapter 11: functions

Golang Functions

A function is a group of statements that exist within a program for the purpose of performing a
specific task. At a high level, a function takes an input and returns an output.

Function allows you to extract commonly used block of code into a single component.

The single most popular Go function is main(), which is used in every independent Go program.
Creating a Function

A declaration begins with the func keyword, followed by the name you want the function to
have, a pair of parentheses (), and then a block containing the function's code.

The following example has a function with the name SimpleFunction. It takes no parameter and
returns no values.

package main

import "fmt"

// SimpleFunction prints a message


func SimpleFunction() {
fmt.Println("Hello World")
}

func main() {
SimpleFunction()
}

When the above code is compiled and executed, it produces the following result −

Hello World

Function with Parameters

Information can be passed to functions through arguments. An argument is just like a variable.

Arguments are specified after the function name, inside the parentheses. You can add as many
arguments as you want, just separate them with a comma.

The following example has a function with two arguments of int type. When the add() function
is called, we pass two integer values (e.g. 20,30).

package main

import "fmt"

// Function accepting arguments


func add(x int, y int) {
total := 0
total = x + y
fmt.Println(total)
}

func main() {
// Passing arguments
add(20, 30)
}
When the above code is compiled and executed, it produces the following result −

50

If the functions with names that start with an uppercase letter will be exported to other packages.
If the function name starts with a lowercase letter, it won't be exported to other packages, but you
can call this function within the same package.

Function with Return Type

In this example, the add() function takes input of two integer numbers and returns an integer
value with a name of total.

Note the return statement is required when a return value is declared as part of the function's
signature.

package main

import "fmt"

// Function with int as return type


func add(x int, y int) int {
total := 0
total = x + y
return total
}

func main() {
// Accepting return value in varaible
sum := add(20, 30)
fmt.Println(sum)
}

The types of input and return value must match with function signature. If we will modify the
above program and pass some string value in argument then program will throw an exception
"cannot use "test" (type string) as type int in argument to add".

Named Return Values

Golang allows you to name the return values of a function. We can also name the return value by
defining variables, here a variable total of integer type is defined in the function declaration for
the value that the function returns.

package main

import "fmt"
func rectangle(l int, b int) (area int) {
var parameter int
parameter = 2 * (l + b)
fmt.Println("Parameter: ", parameter)

area = l * b
return // Return statement without specify variable name
}

func main() {
fmt.Println("Area: ", rectangle(20, 30))
}

When the above code is compiled and executed, it produces the following result −

C:\Golang>go run main.go


Parameter: 100
Area: 600

Since the function is declared to return a value of type int, the last logical statement in the
execution flow must be a return statement that returns a value of the declared type.

Returning Multiple Values

Functions in Golang can return multiple values, which is a helpful feature in many practical
scenarios.

This example declares a function with two return values and calls it from a main function.

package main

import "fmt"

func rectangle(l int, b int) (area int, parameter int) {


parameter = 2 * (l + b)
area = l * b
return // Return statement without specify variable name
}

func main() {
var a, p int
a, p = rectangle(20, 30)
fmt.Println("Area:", a)
fmt.Println("Parameter:", p)
}

Points to remember
 A name must begin with a letter, and can have any number of additional letters and numbers.
 A function name cannot start with a number.

 A function name cannot contain spaces.

 If the functions with names that start with an uppercase letter will be exported to other
packages. If the function name starts with a lowercase letter, it won't be exported to other
packages, but you can call this function within the same package.

 If a name consists of multiple words, each word after the first should be capitalized like this:
empName, EmpAddress, etc.

 function names are case-sensitive (car, Car and CAR are three different variables).

Passing Address to a Function

Passing the address of variable to the function and the value of a variables modified using
dereferencing inside body of function.

package main

import "fmt"

func update(a *int, t *string) {


*a = *a + 5 // defrencing pointer address
*t = *t + " Doe" // defrencing pointer address
return
}

func main() {
var age = 20
var text = "John"
fmt.Println("Before:", text, age)

update(&age, &text)

fmt.Println("After :", text, age)


}

You should see the following output when you run the above program −

C:\Golang>go run main.go


Before: John 20
After : John Doe 25

Anonymous Functions

An anonymous function is a function that was declared without any named identifier to refer to
it. Anonymous functions can accept inputs and return outputs, just as standard functions do.
Assigning function to the variable.

package main

import "fmt"

var (
area = func(l int, b int) int {
return l * b
}
)

func main() {
fmt.Println(area(20, 30))
}

Passing arguments to anonymous functions.

package main

import "fmt"

func main() {
func(l int, b int) {
fmt.Println(l * b)
}(20, 30)
}

Function defined to accept a parameter and return value.

package main

import "fmt"

func main() {
fmt.Printf(
"100 (°F) = %.2f (°C)\n",
func(f float64) float64 {
return (f - 32.0) * (5.0 / 9.0)
}(100),
)
}
Anonymous functions can be used for containing functionality that need not be named and possibly for
short-term use.

Closures Functions

Closures are a special case of anonymous functions. Closures are anonymous functions which
access the variables defined outside the body of the function.
Anonymous function accessing the variable defined outside body.

package main

import "fmt"

func main() {
l := 20
b := 30

func() {
var area int
area = l * b
fmt.Println(area)
}()
}

Anonymous function accessing variable on each iteration of loop inside function body.

package main

import "fmt"

func main() {
for i := 10.0; i < 100; i += 10.0 {
rad := func() float64 {
return i * 39.370
}()
fmt.Printf("%.2f Meter = %.2f Inch\n", i, rad)
}
}

Higher Order Functions

A Higher-Order function is a function that receives a function as an argument or returns the


function as output.

Higher order functions are functions that operate on other functions, either by taking them as
arguments or by returning them.

Passing Functions as Arguments to other Functions


package main

import "fmt"

func sum(x, y int) int {


return x + y
}
func partialSum(x int) func(int) int {
return func(y int) int {
return sum(x, y)
}
}
func main() {
partial := partialSum(3)
fmt.Println(partial(7))
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


10

In the program above, the partialSum function returns a sum function that takes two int
arguments and returns a int argument.

Returning Functions from other Functions


package main

import "fmt"

func squareSum(x int) func(int) func(int) int {


return func(y int) func(int) int {
return func(z int) int {
return x*x + y*y + z*z
}
}
}
func main() {
// 5*5 + 6*6 + 7*7
fmt.Println(squareSum(5)(6)(7))
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


110

In the program above, the squareSum function signature specifying that function returns two
functions and one integer value.

User Defined Function Types

Golang also support to define our own function types.

The modified version of above program with function types as below:

package main

import "fmt"
type First func(int) int
type Second func(int) First

func squareSum(x int) Second {


return func(y int) First {
return func(z int) int {
return x*x + y*y + z*z
}
}
}

func main() {
// 5*5 + 6*6 + 7*7
fmt.Println(squareSum(5)(6)(7))
}

Chapter 12: functions

Golang Functions

A function is a group of statements that exist within a program for the purpose of performing a
specific task. At a high level, a function takes an input and returns an output.

Function allows you to extract commonly used block of code into a single component.

The single most popular Go function is main(), which is used in every independent Go program.

Creating a Function

A declaration begins with the func keyword, followed by the name you want the function to
have, a pair of parentheses (), and then a block containing the function's code.

The following example has a function with the name SimpleFunction. It takes no parameter and
returns no values.

package main

import "fmt"

// SimpleFunction prints a message


func SimpleFunction() {
fmt.Println("Hello World")
}
func main() {
SimpleFunction()
}

When the above code is compiled and executed, it produces the following result −

Hello World

Function with Parameters

Information can be passed to functions through arguments. An argument is just like a variable.

Arguments are specified after the function name, inside the parentheses. You can add as many
arguments as you want, just separate them with a comma.

The following example has a function with two arguments of int type. When the add() function
is called, we pass two integer values (e.g. 20,30).

package main

import "fmt"

// Function accepting arguments


func add(x int, y int) {
total := 0
total = x + y
fmt.Println(total)
}

func main() {
// Passing arguments
add(20, 30)
}

When the above code is compiled and executed, it produces the following result −

50

If the functions with names that start with an uppercase letter will be exported to other packages.
If the function name starts with a lowercase letter, it won't be exported to other packages, but you
can call this function within the same package.

Function with Return Type

In this example, the add() function takes input of two integer numbers and returns an integer
value with a name of total.
Note the return statement is required when a return value is declared as part of the function's
signature.

package main

import "fmt"

// Function with int as return type


func add(x int, y int) int {
total := 0
total = x + y
return total
}

func main() {
// Accepting return value in varaible
sum := add(20, 30)
fmt.Println(sum)
}

The types of input and return value must match with function signature. If we will modify the
above program and pass some string value in argument then program will throw an exception
"cannot use "test" (type string) as type int in argument to add".

Named Return Values

Golang allows you to name the return values of a function. We can also name the return value by
defining variables, here a variable total of integer type is defined in the function declaration for
the value that the function returns.

package main

import "fmt"

func rectangle(l int, b int) (area int) {


var parameter int
parameter = 2 * (l + b)
fmt.Println("Parameter: ", parameter)

area = l * b
return // Return statement without specify variable name
}

func main() {
fmt.Println("Area: ", rectangle(20, 30))
}

When the above code is compiled and executed, it produces the following result −

C:\Golang>go run main.go


Parameter: 100
Area: 600

Since the function is declared to return a value of type int, the last logical statement in the
execution flow must be a return statement that returns a value of the declared type.

Returning Multiple Values

Functions in Golang can return multiple values, which is a helpful feature in many practical
scenarios.

This example declares a function with two return values and calls it from a main function.

package main

import "fmt"

func rectangle(l int, b int) (area int, parameter int) {


parameter = 2 * (l + b)
area = l * b
return // Return statement without specify variable name
}

func main() {
var a, p int
a, p = rectangle(20, 30)
fmt.Println("Area:", a)
fmt.Println("Parameter:", p)
}

Points to remember
 A name must begin with a letter, and can have any number of additional letters and numbers.
 A function name cannot start with a number.

 A function name cannot contain spaces.

 If the functions with names that start with an uppercase letter will be exported to other
packages. If the function name starts with a lowercase letter, it won't be exported to other
packages, but you can call this function within the same package.

 If a name consists of multiple words, each word after the first should be capitalized like this:
empName, EmpAddress, etc.

 function names are case-sensitive (car, Car and CAR are three different variables).
Passing Address to a Function

Passing the address of variable to the function and the value of a variables modified using
dereferencing inside body of function.

package main

import "fmt"

func update(a *int, t *string) {


*a = *a + 5 // defrencing pointer address
*t = *t + " Doe" // defrencing pointer address
return
}

func main() {
var age = 20
var text = "John"
fmt.Println("Before:", text, age)

update(&age, &text)

fmt.Println("After :", text, age)


}

You should see the following output when you run the above program −

C:\Golang>go run main.go


Before: John 20
After : John Doe 25

Anonymous Functions

An anonymous function is a function that was declared without any named identifier to refer to
it. Anonymous functions can accept inputs and return outputs, just as standard functions do.

Assigning function to the variable.

package main

import "fmt"

var (
area = func(l int, b int) int {
return l * b
}
)

func main() {
fmt.Println(area(20, 30))
}
Passing arguments to anonymous functions.

package main

import "fmt"

func main() {
func(l int, b int) {
fmt.Println(l * b)
}(20, 30)
}

Function defined to accept a parameter and return value.

package main

import "fmt"

func main() {
fmt.Printf(
"100 (°F) = %.2f (°C)\n",
func(f float64) float64 {
return (f - 32.0) * (5.0 / 9.0)
}(100),
)
}
Anonymous functions can be used for containing functionality that need not be named and possibly for
short-term use.

Closures Functions

Closures are a special case of anonymous functions. Closures are anonymous functions which
access the variables defined outside the body of the function.

Anonymous function accessing the variable defined outside body.

package main

import "fmt"

func main() {
l := 20
b := 30

func() {
var area int
area = l * b
fmt.Println(area)
}()
}
Anonymous function accessing variable on each iteration of loop inside function body.

package main

import "fmt"

func main() {
for i := 10.0; i < 100; i += 10.0 {
rad := func() float64 {
return i * 39.370
}()
fmt.Printf("%.2f Meter = %.2f Inch\n", i, rad)
}
}

Higher Order Functions

A Higher-Order function is a function that receives a function as an argument or returns the


function as output.

Higher order functions are functions that operate on other functions, either by taking them as
arguments or by returning them.

Passing Functions as Arguments to other Functions


package main

import "fmt"

func sum(x, y int) int {


return x + y
}
func partialSum(x int) func(int) int {
return func(y int) int {
return sum(x, y)
}
}
func main() {
partial := partialSum(3)
fmt.Println(partial(7))
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


10

In the program above, the partialSum function returns a sum function that takes two int
arguments and returns a int argument.

Returning Functions from other Functions


package main
import "fmt"

func squareSum(x int) func(int) func(int) int {


return func(y int) func(int) int {
return func(z int) int {
return x*x + y*y + z*z
}
}
}
func main() {
// 5*5 + 6*6 + 7*7
fmt.Println(squareSum(5)(6)(7))
}

You should see the following output when you run the above program −

C:\Golang>go run main.go


110

In the program above, the squareSum function signature specifying that function returns two
functions and one integer value.

User Defined Function Types

Golang also support to define our own function types.

The modified version of above program with function types as below:

package main

import "fmt"

type First func(int) int


type Second func(int) First

func squareSum(x int) Second {


return func(y int) First {
return func(z int) int {
return x*x + y*y + z*z
}
}
}

func main() {
// 5*5 + 6*6 + 7*7
fmt.Println(squareSum(5)(6)(7))
}
Chapter 13: variadic functions

Variadic Functions
A variadic function is a function that accepts a variable number of arguments. In Golang, it is
possible to pass a varying number of arguments of the same type as referenced in the function
signature. To declare a variadic function, the type of the final parameter is preceded by an
ellipsis, "...", which shows that the function may be called with any number of arguments of this
type. This type of function is useful when you don't know the number of arguments you are
passing to the function, the best example is built-in Println function of the fmt package which is a
variadic function.

Select single argument from all arguments of variadic function.

In below example we will are going to print s[0] the first and s[3] the forth, argument value
passed to variadicExample() function.

package main

import "fmt"

func main() {

variadicExample("red", "blue", "green", "yellow")

func variadicExample(s ...string) {

fmt.Println(s[0])

fmt.Println(s[3])

C:\golang\example>go run test1.go


red
yellow

C:\golang\example>
Needs to be precise when running an empty function call, if the code inside of the function
expecting an argument and absence of argument will generate an error "panic: run-time error:
index out of range". In above example you have to pass at least 4 arguments.

Passing multiple string arguments to a variadic function

The parameter s accepts an infinite number of arguments. The tree-dotted ellipsis tells the
compiler that this string will accept, from zero to multiple values.

package main

import "fmt"

func main() {

variadicExample()

variadicExample("red", "blue")

variadicExample("red", "blue", "green")

variadicExample("red", "blue", "green", "yellow")

func variadicExample(s ...string) {

fmt.Println(s)

C:\golang\example>go run test1.go


[]
[red blue]
[red blue green]
[red blue green yellow]

C:\golang\example>
In the above example, we have called the function with single and multiple arguments; and
without passing any arguments.

Normal function parameter with variadic function parameter


package main

import "fmt"

func main() {

fmt.Println(calculation("Rectangle", 20, 30))

fmt.Println(calculation("Square", 20))

func calculation(str string, y ...int) int {

area := 1

for _, val := range y {

if str == "Rectangle" {

area *= val

} else if str == "Square" {

area = val * val

return area

C:\golang\example>go run test1.go


600
400

C:\golang\example>

Pass different types of arguments in variadic function

In the following example, the function signature accepts an arbitrary number of arguments of
type slice.

package main

import (

"fmt"

"reflect"

func main() {

variadicExample(1, "red", true, 10.5, []string{"foo", "bar", "baz"},

map[string]int{"apple": 23, "tomato": 13})

func variadicExample(i ...interface{}) {

for _, v := range i {

fmt.Println(v, "--", reflect.ValueOf(v).Kind())

C:\golang\example>go run test3.go


1 -- int
red -- string
true -- bool
10.5 -- float64
[foo bar baz] -- slice
map[apple:23 tomato:13] -- map

C:\golang\example>

Chapter 14: deferred function

Deferred Functions Calls


Go has a special statement called defer that schedules a function call to be run after the function
completes. Consider the following example:

package main

import "fmt"

func first() {

fmt.Println("First")

func second() {

fmt.Println("Second")

func main() {

defer second()

first()

This program prints First followed by Second.

A defer statement is often used with paired operations like open and close, connect and
disconnect, or lock and unlock to ensure that resources are released in all cases, no matter how
complex the control flow. The right place for a defer statement that releases a resource is
immediately after the resource has been successfully acquired.

Below is the example to open a file and perform read/write action on it. In this example there are
often spots where you want to return early.
Without defer
func ReadWrite() bool {

file.Open("file")

if failureX {

file.Close() //And here...

return false

if failureY {

file.Close() //And here...

return false

file.Close() //And here...

return true

A lot of code is repeated here. To overcome this Go has the defer statement. The code above
could be rewritten as follows. This makes the function more readable, shorter and puts the Close
right next to the Open.

With defer
func ReadWrite() bool {

file.Open("file")

defer file.Close() //file.Close() is added to defer list

// Do your thing

if failureX {

return false // Close() is now done automatically

if failureY {

return false // And here too


}

return true // And here

This has various advantages:

- It keeps our Close call near our Open call so it's easier to understand.
- If our function had multiple return statements (perhaps one in an if and one in an else), Close
will happen before both of them.
- Deferred Functions are run even if a runtime panic occurs.
- Deferred functions are executed in LIFO order, so the above code prints: 4 3 2 1 0.
- You can put multiple functions on the "deferred list", like this example.

package main

import "fmt"

func main() {

for i := 0; i < 5; i++ {

defer fmt.Printf("%d ", i)

Chapter 15: panic and recover

Panic and Recover


The built-in type system of GO Language catches many mistakes at compile time, but unable to
check mistakes like an out-of-bounds array, access or nil pointer deference which require checks
at run time. GO does not have an exception mechanism you can't throw exceptions. During the
execution when Go detects these mistakes, it panics and stops all normal execution, all deferred
function calls in that goroutine are executed and finally program crashes with a log message.
This log message usually has enough information to analyze the root cause of the problem
without running the program repeatedly, so it should always be included in a bug report about a
panicking program.

Panic is a built-in function that stops the ordinary flow of control and begins panicking. When
the function X calls panic, execution of X stops, any deferred functions in X are executed
normally, and then X returns to its caller. To the caller, X then behaves like a call to panic. The
process continues up the stack until all functions in the current goroutine have returned, at which
point the program crashes. Panics can be initiated by invoking panic directly. They can also be
caused by run-time errors, such as out-of-bounds array accesses.

Not all panics come from the run-time. The built-in panic function may be called directly; it accepts any
value as an argument. A panic is usually the best thing to do when some "impossible" situation happens,
for instance, execution reaches a case that logically can't happen:

package main
import "fmt"
func main() {
var action int
fmt.Println("Enter 1 for Student and 2 for Professional")
fmt.Scanln(&action)
/* Use of Switch Case in Golang */
switch action {
case 1:
fmt.Printf("I am a Student")
case 2:
fmt.Printf("I am a Professional")
default:
panic(fmt.Sprintf("I am a %d",action))
}
fmt.Println("")
fmt.Println("Enter 1 for US and 2 for UK")
fmt.Scanln(&action)
/* Use of Switch Case in Golang */
switch {
case 1:
fmt.Printf("US")
case 2:
fmt.Printf("UK")
default:
panic(fmt.Sprintf("I am a %d",action))
}
}

In above program program will stop execution after first switch-case if user enters any other
value other that 1 or 2.

Recover is a built-in function that regains control of a panicking goroutine. Recover is only useful inside
deferred functions. During normal execution, a call to recover will return nil and have no other effect. If
the current goroutine is panicking, a call to recover will capture the value given to panic and resume
normal execution.

package main
import "fmt"
func main() {
var action int
fmt.Println("Enter 1 for Student and 2 for Professional")
fmt.Scanln(&action)
/* Use of Switch Case in Golang */
switch action {
case 1:
fmt.Printf("I am a Student")
case 2:
fmt.Printf("I am a Professional")
default:
panic(fmt.Sprintf("I am a %d",action))
}
defer func() {
action := recover()
fmt.Println(action)
}()
}

Chapter 16: arrays

Golang Arrays
An array is a data structure that consists of a collection of elements of a single type or simply
you can say a special variable, which can hold more than one value at a time. The values an array
holds are called its elements or items. An array holds a specific number of elements, and it
cannot grow or shrink. Different data types can be handled as elements in arrays such as Int,
String, Boolean, and others. The index of the first element of any dimension of an array is 0, the
index of the second element of any array dimension is 1, and so on.

Declaring an Integer or String Array of Five Elements in Go

To declare an array you need to specify the number of elements it holds in square brackets ([]),
followed by the type of elements the array holds.

package main

import (
"fmt"
"reflect"
)

func main() {
var intArray [5]int
var strArray [5]string

fmt.Println(reflect.ValueOf(intArray).Kind())
fmt.Println(reflect.ValueOf(strArray).Kind())
}
array
array
How to assign and access array element values in Go?

You access or assign the array elements by referring to the index number. The index is specified
in square brackets.

package main

import "fmt"

func main() {
var theArray [3]string
theArray[0] = "India" // Assign a value to the first element
theArray[1] = "Canada" // Assign a value to the second element
theArray[2] = "Japan" // Assign a value to the third element

fmt.Println(theArray[0]) // Access the first element value


fmt.Println(theArray[1]) // Access the second element valu
fmt.Println(theArray[2]) // Access the third element valu
}
India
Canada
Japan

How to initialize an Array with an Array Literal in Go?

You can initialize an array with pre-defined values using an array literal. An array literal have the
number of elements it will hold in square brackets, followed by the type of its elements. This is
followed by a list of initial values separated by commas of each element inside the curly braces.

package main

import "fmt"

func main() {
x := [5]int{10, 20, 30, 40, 50} // Intialized with values
var y [5]int = [5]int{10, 20, 30} // Partial assignment

fmt.Println(x)
fmt.Println(y)
}
[10 20 30 40 50]
[10 20 30 0 0]

Initializing an Array with ellipses in Go

When we use ... instead of specifying the length. The compiler can identify the length of an
array, based on the elements specified in the array declaration.

package main
import (
"fmt"
"reflect"
)

func main() {
x := [...]int{10, 20, 30}

fmt.Println(reflect.ValueOf(x).Kind())
fmt.Println(len(x))
}
array
3

Initialize values for specific array elements in Go

When an array declare using an array literal, values can be initialize for specific elements.

A value of 10 is assigned to the second element (index 1) and a value of 30 is assigned to the fourth
element (index 3).

package main

import "fmt"

func main() {
x := [5]int{1: 10, 3: 30}
fmt.Println(x)
}
[0 10 0 30 0]

How to iterate over an Array using for loop?

You can loop through an array elements by using a for loop.

package main

import "fmt"

func main() {
intArray := [5]int{10, 20, 30, 40, 50}

fmt.Println("\n---------------Example 1--------------------\n")
for i := 0; i < len(intArray); i++ {
fmt.Println(intArray[i])
}

fmt.Println("\n---------------Example 2--------------------\n")
for index, element := range intArray {
fmt.Println(index, "=>", element)
}

fmt.Println("\n---------------Example 3--------------------\n")
for _, value := range intArray {
fmt.Println(value)
}

j := 0
fmt.Println("\n---------------Example 4--------------------\n")
for range intArray {
fmt.Println(intArray[j])
j++
}
}

Copy an array by value and reference into another array

You can create copy of an array, by assigning an array to a new variable either by value or
reference.

package main

import "fmt"

func main() {

strArray1 := [3]string{"Japan", "Australia", "Germany"}


strArray2 := strArray1 // data is passed by value
strArray3 := &strArray1 // data is passed by refrence

fmt.Printf("strArray1: %v\n", strArray1)


fmt.Printf("strArray2: %v\n", strArray2)

strArray1[0] = "Canada"

fmt.Printf("strArray1: %v\n", strArray1)


fmt.Printf("strArray2: %v\n", strArray2)
fmt.Printf("*strArray3: %v\n", *strArray3)
}
strArray1: [Japan Australia Germany]
strArray2: [Japan Australia Germany]
strArray1: [Canada Australia Germany]
strArray2: [Japan Australia Germany]
*strArray3: [Canada Australia Germany]

Golang check if array element exists

To determine if a specific element exist in an array, we need to iterate each array element using
for loop and check using if condition.

package main
import (
"fmt"
"reflect"
)

func main() {
strArray := [5]string{"India", "Canada", "Japan", "Germany", "Italy"}
fmt.Println(itemExists(strArray, "Canada"))
fmt.Println(itemExists(strArray, "Africa"))
}

func itemExists(arrayType interface{}, item interface{}) bool {


arr := reflect.ValueOf(arrayType)

if arr.Kind() != reflect.Array {
panic("Invalid data-type")
}

for i := 0; i < arr.Len(); i++ {


if arr.Index(i).Interface() == item {
return true
}
}

return false
}
true
false

Tricks to filter array elements in Go

You can filter array element using : as shown below

A value of 10 is assigned to the second element (index 1) and a value of 30 is assigned to the fourth
element (index 3).

package main

import "fmt"

func main() {
countries := [...]string{"India", "Canada", "Japan", "Germany",
"Italy"}

fmt.Printf("Countries: %v\n", countries)

fmt.Printf(":2 %v\n", countries[:2])

fmt.Printf("1:3 %v\n", countries[1:3])

fmt.Printf("2: %v\n", countries[2:])

fmt.Printf("2:5 %v\n", countries[2:5])


fmt.Printf("0:3 %v\n", countries[0:3])

fmt.Printf("Last element: %v\n", countries[len(countries)-1])

fmt.Printf("All elements: %v\n", countries[0:len(countries)])


fmt.Println(countries[:])
fmt.Println(countries[0:])
fmt.Println(countries[0:len(countries)])

fmt.Printf("Last two elements: %v\n", countries[len(countries)-


2:len(countries)])
}
Countries: [India Canada Japan Germany Italy]
:2 [India Canada]
1:3 [Canada Japan]
2: [Japan Germany Italy]
2:5 [Japan Germany Italy]
0:3 [India Canada Japan]
Last element: Italy
All elements: [India Canada Japan Germany Italy]
[India Canada Japan Germany Italy]
[India Canada Japan Germany Italy]
[India Canada Japan Germany Italy]
Last two elements: [Germany Italy]

Chapter 17: slices

Golang Slices
A slice is a flexible and extensible data structure to implement and manage collections of data.
Slices are made up of multiple elements, all of the same type. A slice is a segment of dynamic
arrays that can grow and shrink as you see fit. Like arrays, slices are index-able and have a
length. Slices have a capacity and length property.

How to create an empty Slice in Golang?

To declare the type for a variable that holds a slice, use an empty pair of square brackets,
followed by the type of elements the slice will hold.

package main

import (
"fmt"
"reflect"
)

func main() {
var intSlice []int
var strSlice []string

fmt.Println(reflect.ValueOf(intSlice).Kind())
fmt.Println(reflect.ValueOf(strSlice).Kind())
}
Creating empty slice of Integer and String type.

slice
slice

How to create Slice using Make function in Golang?

Slice can be created using the built-in function make. When you use make, one option you have
is to specify the length of the slice. When you just specify the length, the capacity of the slice is
the same.

package main

import (
"fmt"
"reflect"
)

func main() {
var intSlice = make([]int, 10) // when length and capacity is
same
var strSlice = make([]string, 10, 20) // when length and capacity is
different

fmt.Printf("intSlice \tLen: %v \tCap: %v\n", len(intSlice),


cap(intSlice))
fmt.Println(reflect.ValueOf(intSlice).Kind())

fmt.Printf("strSlice \tLen: %v \tCap: %v\n", len(strSlice),


cap(strSlice))
fmt.Println(reflect.ValueOf(strSlice).Kind())
}
You can also specify the length and capacity separately.

intSlice Len: 10 Cap: 10


slice
strSlice Len: 10 Cap: 20
slice

How to initialize the slice with values using a slice literal?

A slice literal contain empty brackets followed by the type of elements the slice will hold, and a
list of the initial values each element will have in curly braces.

package main
import "fmt"

func main() {
var intSlice = []int{10, 20, 30, 40}
var strSlice = []string{"India", "Canada", "Japan"}

fmt.Printf("intSlice \tLen: %v \tCap: %v\n", len(intSlice),


cap(intSlice))
fmt.Printf("strSlice \tLen: %v \tCap: %v\n", len(strSlice),
cap(strSlice))
}

How to create Slice using new keyword in Golang?

A slice can be declare using new keyword followed by capacity in square brackets then type of
elements the slice will hold.

package main

import (
"fmt"
"reflect"
)

func main() {
var intSlice = new([50]int)[0:10]

fmt.Println(reflect.ValueOf(intSlice).Kind())
fmt.Printf("intSlice \tLen: %v \tCap: %v\n", len(intSlice),
cap(intSlice))
fmt.Println(intSlice)
}
slice
intSlice Len: 10 Cap: 50
[0 0 0 0 0 0 0 0 0 0]

How to add items to Slice using append function in Golang?

To add an item to the end of the slice, use the append() method.

package main

import "fmt"

func main() {
a := make([]int, 2, 5)
a[0] = 10
a[1] = 20
fmt.Println("Slice A:", a)
fmt.Printf("Length is %d Capacity is %d\n", len(a), cap(a))
a = append(a, 30, 40, 50, 60, 70, 80, 90)
fmt.Println("Slice A after appending data:", a)
fmt.Printf("Length is %d Capacity is %d\n", len(a), cap(a))
}
If there's sufficient capacity in the underlying slice, the element is placed after the last element and the
length get incremented. However, if there is not sufficient capacity, a new slice is created, all of the
existing elements are copied over, the new element is added onto the end, and the new slice is returned.

Slice A: [10 20]


Length is 2 Capacity is 5
Slice A after appending data: [10 20 30 40 50 60 70 80 90]
Length is 9 Capacity is 12

How to access slice items in Golang?

You access the slice items by referring to the index number.

package main

import "fmt"

func main() {
var intSlice = []int{10, 20, 30, 40}

fmt.Println(intSlice[0])
fmt.Println(intSlice[1])
fmt.Println(intSlice[0:4])
}

How to change slice item value in Golang?

To change the value of a specific item, refer to the index number.

package main

import "fmt"

func main() {
var strSlice = []string{"India", "Canada", "Japan"}
fmt.Println(strSlice)

strSlice[2] = "Germany"
fmt.Println(strSlice)
}
[India Canada Japan]
[India Canada Germany]
How to delete an element from a Slice in Golang?

RemoveIndex function created to remove specific item from String slice.

package main

import "fmt"

func main() {
var strSlice = []string{"India", "Canada", "Japan", "Germany",
"Italy"}
fmt.Println(strSlice)

strSlice = RemoveIndex(strSlice, 3)
fmt.Println(strSlice)
}

func RemoveIndex(s []string, index int) []string {


return append(s[:index], s[index+1:]...)
}
[India Canada Japan Germany Italy]
[India Canada Japan Italy]

How to copy one slice items into another slice in Golang?

The built-in copy function is used to copy data from one slice to another.

package main

import "fmt"

func main() {
a := []int{5, 6, 7} // Create a smaller slice
fmt.Printf("[Slice:A] Length is %d Capacity is %d\n", len(a), cap(a))

b := make([]int, 5, 10) // Create a bigger slice


copy(b, a) // Copy function
fmt.Printf("[Slice:B] Length is %d Capacity is %d\n", len(b), cap(b))

fmt.Println("Slice B after copying:", b)


b[3] = 8
b[4] = 9
fmt.Println("Slice B after adding elements:", b)
}
[Slice:A] Length is 3 Capacity is 3
[Slice:B] Length is 5 Capacity is 10
Slice B after copying: [5 6 7 0 0]
Slice B after adding elements: [5 6 7 8 9]
How to slice elements in Golang?

Slicing is a computationally fast way to methodically access parts of your data.

package main

import "fmt"

func main() {
var countries = []string{"india", "japan", "canada", "australia",
"russia"}

fmt.Printf("Countries: %v\n", countries)

fmt.Printf(":2 %v\n", countries[:2])

fmt.Printf("1:3 %v\n", countries[1:3])

fmt.Printf("2: %v\n", countries[2:])

fmt.Printf("2:5 %v\n", countries[2:5])

fmt.Printf("0:3 %v\n", countries[0:3])

fmt.Printf("Last element: %v\n", countries[4])


fmt.Printf("Last element: %v\n", countries[len(countries)-1])
fmt.Printf("Last element: %v\n", countries[4:])

fmt.Printf("All elements: %v\n", countries[0:len(countries)])

fmt.Printf("Last two elements: %v\n", countries[3:len(countries)])


fmt.Printf("Last two elements: %v\n", countries[len(countries)-
2:len(countries)])

fmt.Println(countries[:])
fmt.Println(countries[0:])
fmt.Println(countries[0:len(countries)])
}
Countries: [india japan canada australia russia]
:2 [india japan]
1:3 [japan canada]
2: [canada australia russia]
2:5 [canada australia russia]
0:3 [india japan canada]
Last element: russia
Last element: russia
Last element: [russia]
All elements: [india japan canada australia russia]
Last two elements: [australia russia]
Last two elements: [australia russia]
[india japan canada australia russia]
[india japan canada australia russia]
[india japan canada australia russia]
How to Iterate Over a Slice in Golang?

You can loop through the list items by using a for loop.

package main

import "fmt"

func main() {
var strSlice = []string{"India", "Canada", "Japan", "Germany",
"Italy"}

fmt.Println("\n---------------Example 1 --------------------\n")
for index, element := range strSlice {
fmt.Println(index, "--", element)
}

fmt.Println("\n---------------Example 2 --------------------\n")
for _, value := range strSlice {
fmt.Println(value)
}

j := 0
fmt.Println("\n---------------Example 3 --------------------\n")
for range strSlice {
fmt.Println(strSlice[j])
j++
}
}

How append a slice to an existing slice in Golang?

The usage of triple-dot ... ellipsis used to append a slice.

package main

import "fmt"

func main() {
var slice1 = []string{"india", "japan", "canada"}
var slice2 = []string{"australia", "russia"}

slice2 = append(slice2, slice1...)


}

How to check if an item exists in Slice in Golang?

To determine if a specified item is present in a slice iterate slice item and check using if
condition.
package main

import (
"fmt"
"reflect"
)

func main() {
var strSlice = []string{"India", "Canada", "Japan", "Germany",
"Italy"}
fmt.Println(itemExists(strSlice, "Canada"))
fmt.Println(itemExists(strSlice, "Africa"))
}

func itemExists(slice interface{}, item interface{}) bool {


s := reflect.ValueOf(slice)

if s.Kind() != reflect.Slice {
panic("Invalid data-type")
}

for i := 0; i < s.Len(); i++ {


if s.Index(i).Interface() == item {
return true
}
}

return false
}

Chapter 18

Golang Maps
In this tutorial you will learn what is a map data type and when to use it in Golang.

A map is a data structure that provides you with an unordered collection of key/value pairs (maps
are also sometimes called associative arrays in Php, hash tables in Java, or dictionaries in
Python). Maps are used to look up a value by its associated key. You store values into the map
based on a key.

The strength of a map is its ability to retrieve data quickly based on the key. A key works like an
index, pointing to the value you associate with that key.

A map is implemented using a hash table, which is providing faster lookups on the data element
and you can easily retrieve a value by providing the key. Maps are unordered collections, and
there's no way to predict the order in which the key/value pairs will be returned. Every iteration
over a map could return a different order.
Map initialization

In Golang maps are written with curly brackets, and they have keys and values. Creating an
instance of a map data type.

package main

import "fmt"

var employee = map[string]int{"Mark": 10, "Sandy": 20}

func main() {
fmt.Println(employee)
}

Empty Map declaration

Map employee created having string as key-type and int as value-type

package main

import "fmt"

func main() {
var employee = map[string]int{}
fmt.Println(employee) // map[]
fmt.Printf("%T\n", employee) // map[string]int
}

Map declaration using make function

The make function takes as argument the type of the map and it returns an initialized map.

package main

import "fmt"

func main() {
var employee = make(map[string]int)
employee["Mark"] = 10
employee["Sandy"] = 20
fmt.Println(employee)

employeeList := make(map[string]int)
employeeList["Mark"] = 10
employeeList["Sandy"] = 20
fmt.Println(employeeList)
}
Map Length

To determine how many items (key-value pairs) a map has, use built-in len() function.

package main

import "fmt"

func main() {
var employee = make(map[string]int)
employee["Mark"] = 10
employee["Sandy"] = 20

// Empty Map
employeeList := make(map[string]int)

fmt.Println(len(employee)) // 2
fmt.Println(len(employeeList)) // 0
}

The len() function will return zero for an uninitialized map.

Accessing Items

You can access the items of a map by referring to its key name, inside square brackets.

package main

import "fmt"

func main() {
var employee = map[string]int{"Mark": 10, "Sandy": 20}

fmt.Println(employee["Mark"])
}

Get the value of the "Mark" key.

Adding Items

Adding an item to the map is done by using a new index key and assigning a value to it.

package main

import "fmt"

func main() {
var employee = map[string]int{"Mark": 10, "Sandy": 20}
fmt.Println(employee) // Initial Map

employee["Rocky"] = 30 // Add element


employee["Josef"] = 40

fmt.Println(employee)
}

Update Values

You can update the value of a specific item by referring to its key name.

package main

import "fmt"

func main() {
var employee = map[string]int{"Mark": 10, "Sandy": 20}
fmt.Println(employee) // Initial Map

employee["Mark"] = 50 // Edit item


fmt.Println(employee)
}

Changed the "Mark" to 50

Delete Items

The built-in delete function deletes an item from a given map associated with the provided key.

package main

import "fmt"

func main() {
var employee = make(map[string]int)
employee["Mark"] = 10
employee["Sandy"] = 20
employee["Rocky"] = 30
employee["Josef"] = 40

fmt.Println(employee)

delete(employee, "Mark")
fmt.Println(employee)
}
Iterate over a Map

The for…range loop statement can be used to fetch the index and element of a map.

package main

import "fmt"

func main() {
var employee = map[string]int{"Mark": 10, "Sandy": 20,
"Rocky": 30, "Rajiv": 40, "Kate": 50}
for key, element := range employee {
fmt.Println("Key:", key, "=>", "Element:", element)
}
}

Each iteration returns a key and its correlated element content.

Truncate Map

There are two methods to clear all items from a Map.

package main

func main() {
var employee = map[string]int{"Mark": 10, "Sandy": 20,
"Rocky": 30, "Rajiv": 40, "Kate": 50}

// Method - I
for k := range employee {
delete(employee, k)
}

// Method - II
employee = make(map[string]int)
}

Sort Map Keys

A Keys slice created to store keys value of map and then sort the slice. The sorted slice used to
print values of map in key order.

package main

import (
"fmt"
"sort"
)
func main() {
unSortedMap := map[string]int{"India": 20, "Canada": 70, "Germany":
15}

keys := make([]string, 0, len(unSortedMap))

for k := range unSortedMap {


keys = append(keys, k)
}
sort.Strings(keys)

for _, k := range keys {


fmt.Println(k, unSortedMap[k])
}
}

Sort Map Values

To sort the key values of a map, you need to store them in Slice and then sort the slice.

package main

import (
"fmt"
"sort"
)

func main() {
unSortedMap := map[string]int{"India": 20, "Canada": 70, "Germany":
15}

// Int slice to store values of map.


values := make([]int, 0, len(unSortedMap))

for _, v := range unSortedMap {


values = append(values, v)
}

// Sort slice values.


sort.Ints(values)

// Print values of sorted Slice.


for _, v := range values {
fmt.Println(v)
}
}

Merge Maps

The keys and values of second map getting added in first map.
package main

import "fmt"

func main() {
first := map[string]int{"a": 1, "b": 2, "c": 3}
second := map[string]int{"a": 1, "e": 5, "c": 3, "d": 4}

for k, v := range second {


first[k] = v
}

fmt.Println(first)
}

Chapter

Golang Struct
A struct (short for "structure") is a collection of data fields with declared data types. Golang has
the ability to declare and create own data types by combining one or more types, including both
built-in and user-defined types. Each data field in a struct is declared with a known type, which
could be a built-in type or another user-defined type.

Structs are the only way to create concrete user-defined types in Golang. Struct types are
declared by composing a fixed set of unique fields. Structs can improve modularity and allow to
create and pass complex data structures around the system. You can also consider Structs as a
template for creating a data record, like an employee record or an e-commerce product.

The declaration starts with the keyword type, then a name for the new struct, and finally the
keyword struct. Within the curly brackets, a series of data fields are specified with a name and a
type.

type identifier struct{


field1 data_type
field2 data_type
field3 data_type
}

Declaration of a struct type

A struct type rectangle is declared that has three data fields of different data-types. Here, struct
used without instantiate a new instance of that type.

package main

import "fmt"
type rectangle struct {
length float64
breadth float64
color string
}

func main() {
fmt.Println(rectangle{10.5, 25.10, "red"})
}

The rectangle struct and its fields are not exported to other packages because identifiers are
started with an lowercase letter. In Golang, identifiers are exported to other packages if the name
starts with an uppercase letter, otherwise the accessibility will be limited within the package only.

Creating Instances of Struct Types

The var keyword initializes a variable rect. Using dot notation, values are assigned to the struct
fields.

package main

import "fmt"

type rectangle struct {


length int
breadth int
color string

geometry struct {
area int
perimeter int
}
}

func main() {
var rect rectangle // dot notation
rect.length = 10
rect.breadth = 20
rect.color = "Green"

rect.geometry.area = rect.length * rect.breadth


rect.geometry.perimeter = 2 * (rect.length + rect.breadth)

fmt.Println(rect)
fmt.Println("Area:\t", rect.geometry.area)
fmt.Println("Perimeter:", rect.geometry.perimeter)
}

The struct is printed to the terminal, showing the values have been assigned.
Creating a Struct Instance Using a Struct Literal

Creates an instance of rectangle struct by using a struct literal and assigning values to the fields
of the struct.

package main

import "fmt"

type rectangle struct {


length int
breadth int
color string
}

func main() {
var rect1 = rectangle{10, 20, "Green"}
fmt.Println(rect1)

var rect2 = rectangle{length: 10, color: "Green"} // breadth value


skipped
fmt.Println(rect2)

rect3 := rectangle{10, 20, "Green"}


fmt.Println(rect3)

rect4 := rectangle{length: 10, breadth: 20, color: "Green"}


fmt.Println(rect4)

rect5 := rectangle{breadth: 20, color: "Green"} // length value


skipped
fmt.Println(rect5)
}

Struct Instantiation using new keyword

An instance of a struct can also be created with the new keyword. It is then possible to assign
data values to the data fields using dot notation.

package main

import "fmt"

type rectangle struct {


length int
breadth int
color string
}

func main() {
rect1 := new(rectangle) // rect1 is a pointer to an instance of
rectangle
rect1.length = 10
rect1.breadth = 20
rect1.color = "Green"
fmt.Println(rect1)

var rect2 = new(rectangle) // rect2 is an instance of rectangle


rect2.length = 10
rect2.color = "Red"
fmt.Println(rect2)
}

Two instances of the rectangle struct are instantiated, rect1 points to the address of the
instantiated struct and rect2 is the name of a struct it represents.

Struct Instantiation Using Pointer Address Operator

Creates an instance of rectangle struct by using a pointer address operator is denoted by &
symbol.

package main

import "fmt"

type rectangle struct {


length int
breadth int
color string
}

func main() {
var rect1 = &rectangle{10, 20, "Green"} // Can't skip any value
fmt.Println(rect1)

var rect2 = &rectangle{}


rect2.length = 10
rect2.color = "Red"
fmt.Println(rect2) // breadth skipped

var rect3 = &rectangle{}


(*rect3).breadth = 10
(*rect3).color = "Blue"
fmt.Println(rect3) // length skipped
}

Nested Struct Type

Struct can be nested by creating a Struct type using other Struct types as the type for the fields of
Struct. Nesting one struct within another can be a useful way to model more complex structures.
package main

import "fmt"

type Salary struct {


Basic, HRA, TA float64
}

type Employee struct {


FirstName, LastName, Email string
Age int
MonthlySalary []Salary
}

func main() {
e := Employee{
FirstName: "Mark",
LastName: "Jones",
Email: "mark@gmail.com",
Age: 25,
MonthlySalary: []Salary{
Salary{
Basic: 15000.00,
HRA: 5000.00,
TA: 2000.00,
},
Salary{
Basic: 16000.00,
HRA: 5000.00,
TA: 2100.00,
},
Salary{
Basic: 17000.00,
HRA: 5000.00,
TA: 2200.00,
},
},
}
fmt.Println(e.FirstName, e.LastName)
fmt.Println(e.Age)
fmt.Println(e.Email)
fmt.Println(e.MonthlySalary[0])
fmt.Println(e.MonthlySalary[1])
fmt.Println(e.MonthlySalary[2])
}

Use Field Tags in the Definition of Struct Type

During the definition of a struct type, optional string values may be added to each field
declaration.

package main

import (
"fmt"
"encoding/json"
)

type Employee struct {


FirstName string `json:"firstname"`
LastName string `json:"lastname"`
City string `json:"city"`
}

func main() {
json_string := `
{
"firstname": "Rocky",
"lastname": "Sting",
"city": "London"
}`

emp1 := new(Employee)
json.Unmarshal([]byte(json_string), emp1)
fmt.Println(emp1)

emp2 := new(Employee)
emp2.FirstName = "Ramesh"
emp2.LastName = "Soni"
emp2.City = "Mumbai"
jsonStr, _ := json.Marshal(emp2)
fmt.Printf("%s\n", jsonStr)
}

The tags are represented as raw string values (wrapped within a pair of ``) and ignored by normal
code execution.

Add Method to Struct Type

You can also add methods to struct types using a method receiver. A method EmpInfo is added
to the Employee struct.

package main

import "fmt"

type Salary struct {


Basic, HRA, TA float64
}

type Employee struct {


FirstName, LastName, Email string
Age int
MonthlySalary []Salary
}
func (e Employee) EmpInfo() string {
fmt.Println(e.FirstName, e.LastName)
fmt.Println(e.Age)
fmt.Println(e.Email)
for _, info := range e.MonthlySalary {
fmt.Println("===================")
fmt.Println(info.Basic)
fmt.Println(info.HRA)
fmt.Println(info.TA)
}
return "----------------------"
}

func main() {

e := Employee{
FirstName: "Mark",
LastName: "Jones",
Email: "mark@gmail.com",
Age: 25,
MonthlySalary: []Salary{
Salary{
Basic: 15000.00,
HRA: 5000.00,
TA: 2000.00,
},
Salary{
Basic: 16000.00,
HRA: 5000.00,
TA: 2100.00,
},
Salary{
Basic: 17000.00,
HRA: 5000.00,
TA: 2200.00,
},
},
}

fmt.Println(e.EmpInfo())
}

Assign Default Value for Struct Field

Method of assigning a custom default value can be achieve by using constructor function.
Instead of creating a struct directly, the Info function can be used to create an Employee struct
with a custom default value for the Name and Age field.

package main

import "fmt"

type Employee struct {


Name string
Age int
}

func (obj *Employee) Info() {


if obj.Name == "" {
obj.Name = "John Doe"
}
if obj.Age == 0 {
obj.Age = 25
}
}

func main() {
emp1 := Employee{Name: "Mr. Fred"}
emp1.Info()
fmt.Println(emp1)

emp2 := Employee{Age: 26}


emp2.Info()
fmt.Println(emp2)
}

This is a technique rather than something that is part of the Golang specification.

Find Type of Struct in Go Programming Language

The reflect package support to check the underlying type of a struct.

package main

import (
"fmt"
"reflect"
)

type rectangle struct {


length float64
breadth float64
color string
}

func main() {
var rect1 = rectangle{10, 20, "Green"}
fmt.Println(reflect.TypeOf(rect1)) // main.rectangle
fmt.Println(reflect.ValueOf(rect1).Kind()) // struct

rect2 := rectangle{length: 10, breadth: 20, color: "Green"}


fmt.Println(reflect.TypeOf(rect2)) // main.rectangle
fmt.Println(reflect.ValueOf(rect2).Kind()) // struct

rect3 := new(rectangle)
fmt.Println(reflect.TypeOf(rect3)) // *main.rectangle
fmt.Println(reflect.ValueOf(rect3).Kind()) // ptr

var rect4 = &rectangle{}


fmt.Println(reflect.TypeOf(rect4)) // *main.rectangle
fmt.Println(reflect.ValueOf(rect4).Kind()) // ptr
}

Comparing Structs with the Different Values Assigned to Data Fields

Structs of the same type can be compared using comparison operator.

package main

import "fmt"

type rectangle struct {


length float64
breadth float64
color string
}

func main() {
var rect1 = rectangle{10, 20, "Green"}
rect2 := rectangle{length: 20, breadth: 10, color: "Red"}

if rect1 == rect2 {
fmt.Println("True")
} else {
fmt.Println("False")
}

rect3 := new(rectangle)
var rect4 = &rectangle{}

if rect3 == rect4 {
fmt.Println("True")
} else {
fmt.Println("False")
}
}

Copy Struct Type Using Value and Pointer Reference

r2 will be the same as r1, it is a copy of r1 rather than a reference to it. Any changes made to r2
will not be applied to r1 and vice versa. When r3 is updated, the underlying memory that is
assigned to r1 is updated.

package main

import "fmt"
type rectangle struct {
length float64
breadth float64
color string
}

func main() {
r1 := rectangle{10, 20, "Green"}
fmt.Println(r1)

r2 := r1
r2.color = "Pink"
fmt.Println(r2)

r3 := &r1
r3.color = "Red"
fmt.Println(r3)

fmt.Println(r1)
}
{10 20 Green}
{10 20 Pink}
&{10 20 Red}
{10 20 Red}

As both r1 and r3 both reference the same underlying memory, their values are the same. Printing
the values of r3 and r1 shows that the values are the same.

Chapter ….

Golang Interface

An Interface is an abstract type.

Interface describes all the methods of a method set and provides the signatures for each method.

To create interface use interface keyword, followed by curly braces containing a list of method
names, along with any parameters or return values the methods are expected to have.

// Declare an Interface Type and methods does not have a body


type Employee interface {
PrintName() string // Method with string return type
PrintAddress(id int) // Method with int parameter
PrintSalary(b int, t int) float64 // Method with parameters and return
type
}

An interfaces act as a blueprint for method sets, they must be implemented before being used.
Type that satisfies an interface is said to implement it.
Define Type that Satisfies an Interface

Defines an interface type named Employee with two methods. Then it defines a type named
Emp that satisfies Employee.

We define all the methods on Emp that it needs to satisfy Employee

package main

import "fmt"

// Employee is an interface for printing employee details


type Employee interface {
PrintName(name string)
PrintSalary(basic int, tax int) int
}

// Emp user-defined type


type Emp int

// PrintName method to print employee name


func (e Emp) PrintName(name string) {
fmt.Println("Employee Id:\t", e)
fmt.Println("Employee Name:\t", name)
}

// PrintSalary method to calculate employee salary


func (e Emp) PrintSalary(basic int, tax int) int {
var salary = (basic * tax) / 100
return basic - salary
}

func main() {
var e1 Employee
e1 = Emp(1)
e1.PrintName("John Doe")
fmt.Println("Employee Salary:", e1.PrintSalary(25000, 5))
}

If a type has all the methods declared in an interface, then no further declarations needed
explicitly to say that Emp satisfies Employee.

Declares an e1 variable with Employee as its type, then creates a Emp value and assigns it to e1.

Define Type that Satisfies Multiple Interfaces

Interfaces allows any user-defined type to satisfy multiple interface types at once.
Using Type Assertion you can get a value of a concrete type back and you can call methods on it
that are defined on other interface, but aren't part of the interface satisfying.

package main

import "fmt"

type Polygons interface {


Perimeter()
}

type Object interface {


NumberOfSide()
}

type Pentagon int

func (p Pentagon) Perimeter() {


fmt.Println("Perimeter of Pentagon", 5*p)
}

func (p Pentagon) NumberOfSide() {


fmt.Println("Pentagon has 5 sides")
}

func main() {
var p Polygons = Pentagon(50)
p.Perimeter()
var o Pentagon = p.(Pentagon)
o.NumberOfSide()

var obj Object = Pentagon(50)


obj.NumberOfSide()
var pent Pentagon = obj.(Pentagon)
pent.Perimeter()
}

When a user-defined type implements the set of methods declared by an interface type, values of
the user-defined type can be assigned to values of the interface type. This assignment stores the
value of the user-defined type into the interface value. When a method call is made against an
interface value, the equivalent method for the stored user-defined value will be executed. Since
any user-defined type can implement any interface, method calls against an interface value are
polymorphic in nature. The user-defined type in this relationship is often referred as concrete
type.

Interfaces with common Method

Two or more interfaces can have one or more common method in list of method sets. Here,
Structure is a common method between two interfaces Vehicle and Human.
package main

import "fmt"

type Vehicle interface {


Structure() []string // Common Method
Speed() string
}

type Human interface {


Structure() []string // Common Method
Performance() string
}

type Car string

func (c Car) Structure() []string {


var parts = []string{"ECU", "Engine", "Air Filters", "Wipers", "Gas
Task"}
return parts
}

func (c Car) Speed() string {


return "200 Km/Hrs"
}

type Man string

func (m Man) Structure() []string {


var parts = []string{"Brain", "Heart", "Nose", "Eyelashes", "Stomach"}
return parts
}

func (m Man) Performance() string {


return "8 Hrs/Day"
}

func main() {
var bmw Vehicle
bmw = Car("World Top Brand")

var labour Human


labour = Man("Software Developer")

for i, j := range bmw.Structure() {


fmt.Printf("%-15s <=====> %15s\n", j, labour.Structure()[i])
}
}

When the above code is compiled and executed, it produces the following result −

C:\Golang>go run main.go


ECU <=====> Brain
Engine <=====> Heart
Air Filters <=====> Nose
Wipers <=====> Eyelashes
Gas Task <=====> Stomach

Interface Accepting Address of the Variable

The Print() methods accept a receiver pointer. Hence, the interface must also accept a receiver
pointer.

If a method accepts a type value, then the interface must receive a type value; if a method has a
pointer receiver, then the interface must receive the address of the variable of the respective type.

package main

import "fmt"

type Book struct {


author, title string
}

type Magazine struct {


title string
issue int
}

func (b *Book) Assign(n, t string) {


b.author = n
b.title = t
}
func (b *Book) Print() {
fmt.Printf("Author: %s, Title: %s\n", b.author, b.title)
}

func (m *Magazine) Assign(t string, i int) {


m.title = t
m.issue = i
}
func (m *Magazine) Print() {
fmt.Printf("Title: %s, Issue: %d\n", m.title, m.issue)
}

type Printer interface {


Print()
}

func main() {
var b Book // Declare instance of Book
var m Magazine // Declare instance of
Magazine
b.Assign("Jack Rabbit", "Book of Rabbits") // Assign values to b via
method
m.Assign("Rabbit Weekly", 26) // Assign values to m via
method

var i Printer // Declare variable of interface type


fmt.Println("Call interface")
i = &b // Method has pointer receiver, interface does not
i.Print() // Show book values via the interface
i = &m // Magazine also satisfies shower interface
i.Print() // Show magazine values via the interface
}

Empty Interface Type

The type interface{} is known as the empty interface, and it is used to accept values of any type.
The empty interface doesn't have any methods that are required to satisfy it, and so every type
satisfies it.

package main

import "fmt"

func printType(i interface{}) {


fmt.Println(i)
}

func main() {
var manyType interface{}
manyType = 100
fmt.Println(manyType)

manyType = 200.50
fmt.Println(manyType)

manyType = "Germany"
fmt.Println(manyType)

printType("Go programming language")


var countries = []string{"india", "japan", "canada", "australia",
"russia"}
printType(countries)

var employee = map[string]int{"Mark": 10, "Sandy": 20}


printType(employee)

country := [3]string{"Japan", "Australia", "Germany"}


printType(country)
}

The manyType variable is declared to be of the type interface{} and it is able to be assigned
values of different types. The printType() function takes a parameter of the type interface{},
hence this function can take the values of any valid type.

When the above code is compiled and executed, it produces the following result −

go run main.go
100
200.5
Germany
Go programming language
[india japan canada australia russia]
map[Mark:10 Sandy:20]
[Japan Australia Germany]

Polymorphism

Polymorphism is the ability to write code that can take on different behavior through the
implementation of types.

We have the declaration of a structs named Pentagon, Hexagon, Octagon and Decagon with the
implementation of the Geometry interface.

package main

import (
"fmt"
)

// Geometry is an interface that defines Geometrical Calculation


type Geometry interface {
Edges() int
}

// Pentagon defines a geometrical object


type Pentagon struct{}

// Hexagon defines a geometrical object


type Hexagon struct{}

// Octagon defines a geometrical object


type Octagon struct{}

// Decagon defines a geometrical object


type Decagon struct{}

// Edges implements the Geometry interface


func (p Pentagon) Edges() int { return 5 }

// Edges implements the Geometry interface


func (h Hexagon) Edges() int { return 6 }

// Edges implements the Geometry interface


func (o Octagon) Edges() int { return 8 }

// Edges implements the Geometry interface


func (d Decagon) Edges() int { return 10 }

// Parameter calculate parameter of object


func Parameter(geo Geometry, value int) int {
num := geo.Edges()
calculation := num * value
return calculation
}

// main is the entry point for the application.


func main() {
p := new(Pentagon)
h := new(Hexagon)
o := new(Octagon)
d := new(Decagon)

g := [...]Geometry{p, h, o, d}

for _, i := range g {
fmt.Println(Parameter(i, 5))
}
}

When the above code is compiled and executed, it produces the following result −

C:\Golang>go run main.go


25
30
40
50

We have our polymorphic Edges functions that accepts values that implement the Geometry
interface. Using polymorphic approach the method created here Parameter is used by each
concrete type value that's passed in.

Interface Embedding

Interfaces may embed other interfaces, this behavior is an aspect of interface polymorphism
which is known as ad hoc polymorphism.

package main

import "fmt"

type Geometry interface {


Edges() int
}

type Polygons interface {


Geometry // Interface embedding another interface
}

type Pentagon int


type Hexagon int
type Octagon int
type Decagon int
func (p Pentagon) Edges() int { return 5 }
func (h Hexagon) Edges() int { return 6 }
func (o Octagon) Edges() int { return 8 }
func (d Decagon) Edges() int { return 10 }

func main() {
p := new(Pentagon)
h := new(Hexagon)
o := new(Octagon)
d := new(Decagon)

polygons := [...]Polygons{p, h, o, d}
for i := range polygons {
fmt.Println(polygons[i].Edges())
}
}

When one type is embedded into another type, the methods of the embedded type are available to
the embedding type. The method or methods of the embedded interface are accessible to the
embedding interface.

Chapter …

Golang Goroutines

Concurrency in Golang is the ability for functions to run independent of each other. Goroutines
are functions that are run concurrently. Golang provides Goroutines as a way to handle
operations concurrently.

New goroutines are created by the go statement.

To run a function as a goroutine, call that function prefixed with the go statement. Here is the
example code block:

sum() // A normal function call that executes sum synchronously and waits
for completing it
go sum() // A goroutine that executes sum asynchronously and doesn't wait for
completing it

The go keyword makes the function call to return immediately, while the function starts running
in the background as a goroutine and the rest of the program continues its execution. The main
function of every Golang program is started using a goroutine, so every Golang program runs at
least one goroutine.
Creating Goroutines

Added the go keyword before each call of function responseSize. The three responseSize
goroutines starts up concurrently and three calls to http.Get are made concurrently as well. The
program doesn't wait until one response comes back before sending out the next request. As a
result the three response sizes are printed much sooner using goroutines.

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)

func responseSize(url string) {


fmt.Println("Step1: ", url)
response, err := http.Get(url)
if err != nil {
log.Fatal(err)
}

fmt.Println("Step2: ", url)


defer response.Body.Close()

fmt.Println("Step3: ", url)


body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println("Step4: ", len(body))
}

func main() {
go responseSize("https://www.golangprograms.com")
go responseSize("https://coderwall.com")
go responseSize("https://stackoverflow.com")
time.Sleep(10 * time.Second)
}

We have added a call to time.Sleep in the main function which prevents the main goroutine from
exiting before the responseSize goroutines can finish. Calling time.Sleep(10 * time.Second) will
make the main goroutine to sleep for 10 seconds.

You may see the following output when you run the above program −

C:\Golang\goroutines\create-simple-goroutine>go run main.go


Step1: https://www.golangprograms.com
Step1: https://stackoverflow.com
Step1: https://coderwall.com
Step2: https://stackoverflow.com
Step3: https://stackoverflow.com
Step4: 116749
Step2: https://www.golangprograms.com
Step3: https://www.golangprograms.com
Step4: 79551
Step2: https://coderwall.com
Step3: https://coderwall.com
Step4: 203842

Waiting for Goroutines to Finish Execution

The WaitGroup type of sync package, is used to wait for the program to finish all goroutines
launched from the main function. It uses a counter that specifies the number of goroutines, and
Wait blocks the execution of the program until the WaitGroup counter is zero.

The Add method is used to add a counter to the WaitGroup.

The Done method of WaitGroup is scheduled using a defer statement to decrement the
WaitGroup counter.

The Wait method of the WaitGroup type waits for the program to finish all goroutines.

The Wait method is called inside the main function, which blocks execution until the WaitGroup
counter reaches the value of zero and ensures that all goroutines are executed.

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
)

// WaitGroup is used to wait for the program to finish goroutines.


var wg sync.WaitGroup

func responseSize(url string) {


// Schedule the call to WaitGroup's Done to tell goroutine is
completed.
defer wg.Done()

fmt.Println("Step1: ", url)


response, err := http.Get(url)
if err != nil {
log.Fatal(err)
}

fmt.Println("Step2: ", url)


defer response.Body.Close()

fmt.Println("Step3: ", url)


body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println("Step4: ", len(body))
}

func main() {
// Add a count of three, one for each goroutine.
wg.Add(3)
fmt.Println("Start Goroutines")

go responseSize("https://www.golangprograms.com")
go responseSize("https://stackoverflow.com")
go responseSize("https://coderwall.com")

// Wait for the goroutines to finish.


wg.Wait()
fmt.Println("Terminating Program")
}

You may see the following output when you run the above program −

C:\Golang\goroutines\create-simple-goroutine>go run main.go


Start Goroutines
Step1: https://coderwall.com
Step1: https://www.golangprograms.com
Step1: https://stackoverflow.com
Step2: https://stackoverflow.com
Step3: https://stackoverflow.com
Step4: 116749
Step2: https://www.golangprograms.com
Step3: https://www.golangprograms.com
Step4: 79801
Step2: https://coderwall.com
Step3: https://coderwall.com
Step4: 203842
Terminating Program

Fetch Values from Goroutines

The most natural way to fetch a value from a goroutine is channels. Channels are the pipes that
connect concurrent goroutines. You can send values into channels from one goroutine and
receive those values into another goroutine or in a synchronous function.

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
)

// WaitGroup is used to wait for the program to finish goroutines.


var wg sync.WaitGroup

func responseSize(url string, nums chan int) {


// Schedule the call to WaitGroup's Done to tell goroutine is
completed.
defer wg.Done()

response, err := http.Get(url)


if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
// Send value to the unbuffered channel
nums <- len(body)
}

func main() {
nums := make(chan int) // Declare a unbuffered channel
wg.Add(1)
go responseSize("https://www.golangprograms.com", nums)
fmt.Println(<-nums) // Read the value from unbuffered channel
wg.Wait()
close(nums) // Closes the channel
}

You may see the following output when you run the above program −

C:\Golang\goroutines\create-simple-goroutine>go run main.go


79655

Play and Pause Execution of Goroutine

Using channels we can play and pause execution of goroutine. A channel handles this
communication by acting as a conduit between goroutines.

package main

import (
"fmt"
"sync"
"time"
)

var i int

func work() {
time.Sleep(250 * time.Millisecond)
i++
fmt.Println(i)
}

func routine(command <-chan string, wg *sync.WaitGroup) {


defer wg.Done()
var status = "Play"
for {
select {
case cmd := <-command:
fmt.Println(cmd)
switch cmd {
case "Stop":
return
case "Pause":
status = "Pause"
default:
status = "Play"
}
default:
if status == "Play" {
work()
}
}
}
}

func main() {
var wg sync.WaitGroup
wg.Add(1)
command := make(chan string)
go routine(command, &wg)

time.Sleep(1 * time.Second)
command <- "Pause"

time.Sleep(1 * time.Second)
command <- "Play"

time.Sleep(1 * time.Second)
command <- "Stop"

wg.Wait()
}

You can see the following output when you run the above program −

1
2
3
4
Pause
Play
5
6
7
8
9
Stop

Fix Race Condition using Atomic Functions

Race conditions occur due to unsynchronized access to shared resource and attempt to read and
write to that resource at the same time.

Atomic functions provide low-level locking mechanisms for synchronizing access to integers
and pointers. Atomic functions generally used to fix the race condition.

The functions in the atomic under sync packages provides support to synchronize goroutines by
locking access to shared resources.

package main

import (
"fmt"
"runtime"
"sync"
"sync/atomic"
)

var (
counter int32 // counter is a variable incremented by all
goroutines.
wg sync.WaitGroup // wg is used to wait for the program to
finish.
)

func main() {
wg.Add(3) // Add a count of two, one for each goroutine.

go increment("Python")
go increment("Java")
go increment("Golang")

wg.Wait() // Wait for the goroutines to finish.


fmt.Println("Counter:", counter)

func increment(name string) {


defer wg.Done() // Schedule the call to Done to tell main we are done.

for range name {


atomic.AddInt32(&counter, 1)
runtime.Gosched() // Yield the thread and be placed back in
queue.
}
}

The AddInt32 function from the atomic package synchronizes the adding of integer values by
enforcing that only one goroutine can perform and complete this add operation at a time. When
goroutines attempt to call any atomic function, they're automatically synchronized against the
variable that's referenced.

You can see the following output when you run the above program −

C:\Golang\goroutines>go run -race main.go


Counter: 15

C:\Golang\goroutines>

Note if you replace the code line atomic.AddInt32(&counter, 1) with counter++, then you will
see the below output-

C:\Golang\goroutines>go run -race main.go


==================
WARNING: DATA RACE
Read at 0x0000006072b0 by goroutine 7:
main.increment()
C:/Golang/goroutines/main.go:31 +0x76

Previous write at 0x0000006072b0 by goroutine 8:


main.increment()
C:/Golang/goroutines/main.go:31 +0x90

Goroutine 7 (running) created at:


main.main()
C:/Golang/goroutines/main.go:18 +0x7e

Goroutine 8 (running) created at:


main.main()
C:/Golang/goroutines/main.go:19 +0x96
==================
Counter: 15
Found 1 data race(s)
exit status 66

C:\Golang\goroutines>

Define Critical Sections using Mutex

A mutex is used to create a critical section around code that ensures only one goroutine at a time
can execute that code section.
package main

import (
"fmt"
"sync"
)

var (
counter int32 // counter is a variable incremented by all
goroutines.
wg sync.WaitGroup // wg is used to wait for the program to
finish.
mutex sync.Mutex // mutex is used to define a critical section
of code.
)

func main() {
wg.Add(3) // Add a count of two, one for each goroutine.

go increment("Python")
go increment("Go Programming Language")
go increment("Java")

wg.Wait() // Wait for the goroutines to finish.


fmt.Println("Counter:", counter)

func increment(lang string) {


defer wg.Done() // Schedule the call to Done to tell main we are done.

for i := 0; i < 3; i++ {


mutex.Lock()
{
fmt.Println(lang)
counter++
}
mutex.Unlock()
}
}

A critical section defined by the calls to Lock() and Unlock() protects the actions against the
counter variable and reading the text of name variable. You can see the following output when
you run the above program −

C:\Golang\goroutines>go run -race main.go


PHP stands for Hypertext Preprocessor.
PHP stands for Hypertext Preprocessor.
The Go Programming Language, also commonly referred to as Golang
The Go Programming Language, also commonly referred to as Golang
Counter: 4

C:\Golang\goroutines>
Chapter ……

Working with Channels


Go provides a mechanism called a channel that is used to share data between goroutines. When
you execute a concurrent activity as a goroutine a resource or data needs to be shared between
goroutines, channels act as a conduit(pipe) between the goroutines and provide a mechanism that
guarantees a synchronous exchange.
Data type need to be specified at the time of declaration of a channel. We can share Values and
pointers of built-in, named, struct, and reference types. Data are passed around on channels: only
one goroutine has access to a data item at any given time: so data races cannot occur, by design.

There are two types of channels based on their behavior of data exchange: unbuffered channels
and buffered channels. An unbuffered channel is used to perform synchronous communication
between goroutines while a buffered channel is used for perform asynchronous communication.
An unbuffered channel provides a guarantee that an exchange between two goroutines is
performed at the instant the send and receive take place. A buffered channel has no such
guarantee.

A channel is created by the make function, which specifies the chan keyword and a
channel's element type.

Here is the code block that creates an unbuffered and buffered channel:
Unbuffered := make(chan int) // Unbuffered channel of integer type

buffered := make(chan int, 10) // Buffered channel of integer type

The use of the built-in function make to create both an unbuffered and buffered channel. The first
argument to make requires the keyword chan and then the type of data the channel will allow to
be exchanged.

Here is the code block to send a value into a channel requires the use of the <- operator:
goroutine1 := make(chan string, 5) // Buffered channel of strings.

goroutine1 <- "Australia" // Send a string through the channel.

A goroutine1 channel of type string that contains a buffer of 5 values. Then we send the string
"Australia" through the channel.

Here is the code block that receives values from a channel:


data := <-goroutine1 // Receive a string from the channel.

The <- operator is attached to the left side of the channel variable(goroutine1), to receive a value
from a channel.
Unbuffered channels

In unbuffered channel there is no capacity to hold any value before it's received. In this type of
channels both a sending and receiving goroutine to be ready at the same instant before any send
or receive operation can complete. If the two goroutines aren't ready at the same instant, the
channel makes the goroutine that performs its respective send or receive operation first wait.
Synchronization is fundamental in the interaction between the send and receive on the channel.
One can't happen without the other.

Buffered channels

In buffered channel there is a capacity to hold one or more values before they're received. In this
types of channels don't force goroutines to be ready at the same instant to perform sends and
receives. There are also different conditions for when a send or receive does block. A receive will
block only if there's no value in the channel to receive. A send will block only if there's no
available buffer to place the value being sent.

// Simple program to demonstrate use of Buffered Channel

package main

import (

"fmt"

"math/rand"

"sync"

"time"

var goRoutine sync.WaitGroup

func main(){

rand.Seed(time.Now().Unix())
// Create a buffered channel to manage the employee vs project load.

projects := make(chan string,10)

// Launch 5 goroutines to handle the projects.

goRoutine.Add(5)

for i :=1; i <= 5; i++ {

go employee(projects, i)

for j :=1; j <= 10; j++ {

projects <- fmt.Sprintf("Project :%d", j)

// Close the channel so the goroutines will quit

close(projects)

goRoutine.Wait()

func employee(projects chan string, employee int) {

defer goRoutine.Done()

for {

// Wait for project to be assigned.

project, result := <-projects

if result==false {

// This means the channel is empty and closed.

fmt.Printf("Employee : %d : Exit\n", employee)


return

fmt.Printf("Employee : %d : Started %s\n", employee, project)

// Randomly wait to simulate work time.

sleep := rand.Int63n(50)

time.Sleep(time.Duration(sleep) * time.Millisecond)

// Display time to wait

fmt.Println("\nTime to sleep",sleep,"ms\n")

// Display project completed by employee.

fmt.Printf("Employee : %d : Completed %s\n", employee, project)

Every time you run this program the output for this program will be different this is because of
the random nature of the program and the Go scheduler.
In above program, a buffered channel of type string is created with a capacity of 10. WaitGroup
is given the count of 5, one for each goroutine. 10 strings are sent into the channel to simulate or
replicate project for the goroutines. Once the last string is sent into the channel, the channel is
going to be closed and the main function waits for all the project to be completed.

Chapter …

Golang Concurrency
Concurrency is an ability of a program to do multiple things at the same time. This means a
program that have two or more tasks that run individually of each other, at about the same time,
but remain part of the same program. Concurrency is very important in modern software, due to
the need to execute independent pieces of code as fast as possible without disturbing the overall
flow of the program.
Concurrency in Golang is the ability for functions to run independent of each other. A goroutine
is a function that is capable of running concurrently with other functions. When you create a
function as a goroutine, it has been treated as an independent unit of work that gets scheduled
and then executed on an available logical processor. The Golang runtime scheduler has feature to
manages all the goroutines that are created and need processor time. The scheduler binds
operating system's threads to logical processors in order to execute the goroutines. By sitting on
top of the operating system, scheduler controls everything related to which goroutines are
running on which logical processors at any given time.

Popular programming languages such as Java and Python implement concurrency by using
threads. Golang has built-in concurrency constructs: goroutines and channels. Concurrency in
Golang is cheap and easy. Goroutines are cheap, lightweight threads. Channels, are the conduits
that allow for communication between goroutines.

Communicating Sequential Processes, or CSP for short, is used to describe how systems that
feature multiple concurrent models should interact with one another. It typically relies heavily on
using channels as a medium for passing messages between two or more concurrent processes,
and is the underlying mantra of Golang.

Goroutines — A goroutine is a function that runs independently of the function that started it.
Channels — A channel is a pipeline for sending and receiving data. Channels provide a way for
one goroutine to send structured data to another.

Concurrency and parallelism comes into the picture when you are examining for multitasking
and they are often used interchangeably, concurrent and parallel refer to related but different
things.

Concurrency - Concurrency is about to handle numerous tasks at once. This means that you are
working to manage numerous tasks done at once in a given period of time. However, you will
only be doing a single task at a time. This tends to happen in programs where one task is waiting
and the program determines to drive another task in the idle time. It is an aspect of the problem
domain — where your program needs to handle numerous simultaneous events.

Parallelism - Parallelism is about doing lots of tasks at once. This means that even if we have
two tasks, they are continuously working without any breaks in between them. It is an aspect of
the solution domain — where you want to make your program faster by processing different
portions of the problem in parallel.

A concurrent program has multiple logical threads of control. These threads may or may not run
in parallel. A parallel program potentially runs more quickly than a sequential program by
executing different parts of the computation simultaneously (in parallel). It may or may not have
more than one logical thread of control.
Illustration of the dining philosophers problem in Golang

Five silent philosophers sit at a round table with bowls of spaghetti. Forks are placed between
each pair of adjacent philosophers. Each philosopher must alternately think and eat. However, a
philosopher can only eat spaghetti when they have both left and right forks. Each fork can be
held by only one philosopher and so a philosopher can use the fork only if it is not being used by
another philosopher. After an individual philosopher finishes eating, they need to put down both
forks so that the forks become available to others. A philosopher can take the fork on their right
or the one on their left as they become available, but cannot start eating before getting both forks.
Eating is not limited by the remaining amounts of spaghetti or stomach space; an infinite supply
and an infinite demand are assumed. The problem is how to design a discipline of behavior (a
concurrent algorithm) such that no philosopher will starve; i.e., each can forever continue to
alternate between eating and thinking, assuming that no philosopher can know when others may
want to eat or think.

package main

import (
"hash/fnv"
"log"
"math/rand"
"os"
"sync"
"time"
)

// Number of philosophers is simply the length of this list.


var ph = []string{"Mark", "Russell", "Rocky", "Haris", "Root"}

const hunger = 3 // Number of times each philosopher eats


const think = time.Second / 100 // Mean think time
const eat = time.Second / 100 // Mean eat time

var fmt = log.New(os.Stdout, "", 0)

var dining sync.WaitGroup

func diningProblem(phName string, dominantHand, otherHand *sync.Mutex) {


fmt.Println(phName, "Seated")
h := fnv.New64a()
h.Write([]byte(phName))
rg := rand.New(rand.NewSource(int64(h.Sum64())))
rSleep := func(t time.Duration) {
time.Sleep(t/2 + time.Duration(rg.Int63n(int64(t))))
}
for h := hunger; h > 0; h-- {
fmt.Println(phName, "Hungry")
dominantHand.Lock() // pick up forks
otherHand.Lock()
fmt.Println(phName, "Eating")
rSleep(eat)
dominantHand.Unlock() // put down forks
otherHand.Unlock()
fmt.Println(phName, "Thinking")
rSleep(think)
}
fmt.Println(phName, "Satisfied")
dining.Done()
fmt.Println(phName, "Left the table")
}

func main() {
fmt.Println("Table empty")
dining.Add(5)
fork0 := &sync.Mutex{}
forkLeft := fork0
for i := 1; i < len(ph); i++ {
forkRight := &sync.Mutex{}
go diningProblem(ph[i], forkLeft, forkRight)
forkLeft = forkRight
}
go diningProblem(ph[0], fork0, forkLeft)
dining.Wait() // wait for philosphers to finish
fmt.Println("Table empty")
}
Table empty
Mark seated
Mark Hungry
Mark Eating
..................
..................
Haris Thinking
Haris Satisfied
Haris Left the table
Table empty

Illustration of Checkpoint Synchronization in Golang

The checkpoint synchronization is a problem of synchronizing multiple tasks. Consider a


workshop where several workers assembling details of some mechanism. When each of them
completes his work, they put the details together. There is no store, so a worker who finished its
part first must wait for others before starting another one. Putting details together is the
checkpoint at which tasks synchronize themselves before going their paths apart.

package main

import (
"log"
"math/rand"
"sync"
"time"
)

func worker(part string) {


log.Println(part, "worker begins part")
time.Sleep(time.Duration(rand.Int63n(1e6)))
log.Println(part, "worker completes part")
wg.Done()
}

var (
partList = []string{"A", "B", "C", "D"}
nAssemblies = 3
wg sync.WaitGroup
)

func main() {
rand.Seed(time.Now().UnixNano())
for c := 1; c <= nAssemblies; c++ {
log.Println("begin assembly cycle", c)
wg.Add(len(partList))
for _, part := range partList {
go worker(part)
}
wg.Wait()
log.Println("assemble. cycle", c, "complete")
}
}
2019/07/15 16:10:32 begin assembly cycle 1
2019/07/15 16:10:32 D worker begins part
2019/07/15 16:10:32 A worker begins part
2019/07/15 16:10:32 B worker begins part
........
2019/07/15 16:10:32 D worker completes part
2019/07/15 16:10:32 C worker completes part
2019/07/15 16:10:32 assemble. cycle 3 complete

Illustration of Producer Consumer Problem in Golang

The problem describes two processes, the producer and the consumer, who share a common,
fixed-size buffer used as a queue. The producer's job is to generate data, put it into the buffer, and
start again. At the same time, the consumer is consuming the data (i.e., removing it from the
buffer), one piece at a time. The problem is to make sure that the producer won't try to add data
into the buffer if it's full and that the consumer won't try to remove data from an empty buffer.
The solution for the producer is to either go to sleep or discard data if the buffer is full. The next
time the consumer removes an item from the buffer, it notifies the producer, who starts to fill the
buffer again. In the same way, the consumer can go to sleep if it finds the buffer empty. The next
time the producer puts data into the buffer, it wakes up the sleeping consumer.

package main

import (
"flag"
"fmt"
"log"
"os"
"runtime"
"runtime/pprof"
)

type Consumer struct {


msgs *chan int
}

// NewConsumer creates a Consumer


func NewConsumer(msgs *chan int) *Consumer {
return &Consumer{msgs: msgs}
}

// consume reads the msgs channel


func (c *Consumer) consume() {
fmt.Println("consume: Started")
for {
msg := <-*c.msgs
fmt.Println("consume: Received:", msg)
}
}

// Producer definition
type Producer struct {
msgs *chan int
done *chan bool
}

// NewProducer creates a Producer


func NewProducer(msgs *chan int, done *chan bool) *Producer {
return &Producer{msgs: msgs, done: done}
}

// produce creates and sends the message through msgs channel


func (p *Producer) produce(max int) {
fmt.Println("produce: Started")
for i := 0; i < max; i++ {
fmt.Println("produce: Sending ", i)
*p.msgs <- i
}
*p.done <- true // signal when done
fmt.Println("produce: Done")
}

func main() {
// profile flags
cpuprofile := flag.String("cpuprofile", "", "write cpu profile to
`file`")
memprofile := flag.String("memprofile", "", "write memory profile to
`file`")

// get the maximum number of messages from flags


max := flag.Int("n", 5, "defines the number of messages")

flag.Parse()

// utilize the max num of cores available


runtime.GOMAXPROCS(runtime.NumCPU())
// CPU Profile
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}

var msgs = make(chan int) // channel to send messages


var done = make(chan bool) // channel to control when production is
done

// Start a goroutine for Produce.produce


go NewProducer(&msgs, &done).produce(*max)

// Start a goroutine for Consumer.consume


go NewConsumer(&msgs).consume()

// Finish the program when the production is done


<-done

// Memory Profile
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f.Close()
}
}
consume: Started
produce: Started
produce: Sending 0
produce: Sending 1
consume: Received: 0
consume: Received: 1
produce: Sending 2
produce: Sending 3
consume: Received: 2
consume: Received: 3
produce: Sending 4
produce: Done
Illustration of Sleeping Barber Problem in Golang

The barber has one barber's chair in a cutting room and a waiting room containing a number of
chairs in it. When the barber finishes cutting a customer's hair, he dismisses the customer and
goes to the waiting room to see if there are others waiting. If there are, he brings one of them
back to the chair and cuts their hair. If there are none, he returns to the chair and sleeps in it.
Each customer, when they arrive, looks to see what the barber is doing. If the barber is sleeping,
the customer wakes him up and sits in the cutting room chair. If the barber is cutting hair, the
customer stays in the waiting room. If there is a free chair in the waiting room, the customer sits
in it and waits their turn. If there is no free chair, the customer leaves.

package main

import (
"fmt"
"sync"
"time"
)

const (
sleeping = iota
checking
cutting
)

var stateLog = map[int]string{


0: "Sleeping",
1: "Checking",
2: "Cutting",
}
var wg *sync.WaitGroup // Amount of potentional customers

type Barber struct {


name string
sync.Mutex
state int // Sleeping/Checking/Cutting
customer *Customer
}

type Customer struct {


name string
}

func (c *Customer) String() string {


return fmt.Sprintf("%p", c)[7:]
}

func NewBarber() (b *Barber) {


return &Barber{
name: "Sam",
state: sleeping,
}
}
// Barber goroutine
// Checks for customers
// Sleeps - wait for wakers to wake him up
func barber(b *Barber, wr chan *Customer, wakers chan *Customer) {
for {
b.Lock()
defer b.Unlock()
b.state = checking
b.customer = nil

// checking the waiting room


fmt.Printf("Checking waiting room: %d\n", len(wr))
time.Sleep(time.Millisecond * 100)
select {
case c := <-wr:
HairCut(c, b)
b.Unlock()
default: // Waiting room is empty
fmt.Printf("Sleeping Barber - %s\n", b.customer)
b.state = sleeping
b.customer = nil
b.Unlock()
c := <-wakers
b.Lock()
fmt.Printf("Woken by %s\n", c)
HairCut(c, b)
b.Unlock()
}
}
}

func HairCut(c *Customer, b *Barber) {


b.state = cutting
b.customer = c
b.Unlock()
fmt.Printf("Cutting %s hair\n", c)
time.Sleep(time.Millisecond * 100)
b.Lock()
wg.Done()
b.customer = nil
}

// customer goroutine
// just fizzles out if it's full, otherwise the customer
// is passed along to the channel handling it's haircut etc
func customer(c *Customer, b *Barber, wr chan<- *Customer, wakers chan<-
*Customer) {
// arrive
time.Sleep(time.Millisecond * 50)
// Check on barber
b.Lock()
fmt.Printf("Customer %s checks %s barber | room: %d, w %d - customer:
%s\n",
c, stateLog[b.state], len(wr), len(wakers), b.customer)
switch b.state {
case sleeping:
select {
case wakers <- c:
default:
select {
case wr <- c:
default:
wg.Done()
}
}
case cutting:
select {
case wr <- c:
default: // Full waiting room, leave shop
wg.Done()
}
case checking:
panic("Customer shouldn't check for the Barber when Barber is
Checking the waiting room")
}
b.Unlock()
}

func main() {
b := NewBarber()
b.name = "Rocky"
WaitingRoom := make(chan *Customer, 5) // 5 chairs
Wakers := make(chan *Customer, 1) // Only one waker at a time
go barber(b, WaitingRoom, Wakers)

time.Sleep(time.Millisecond * 100)
wg = new(sync.WaitGroup)
n := 10
wg.Add(10)
// Spawn customers
for i := 0; i < n; i++ {
time.Sleep(time.Millisecond * 50)
c := new(Customer)
go customer(c, b, WaitingRoom, Wakers)
}

wg.Wait()
fmt.Println("No more customers for the day")
}
Checking waiting room: 0
Sleeping Barber - <nil>
Customer 120 checks Sleeping barber | room: 0, w 0 - customer: <nil>
Woken by 120
..............
..............
Checking waiting room: 0
No more customers for the day
Illustration of Cigarette Smokers Problem in Golang

Assume a cigarette requires three ingredients to make and smoke: tobacco, paper, and matches.
There are three smokers around a table, each of whom has an infinite supply of one of the three
ingredients — one smoker has an infinite supply of tobacco, another has paper, and the third has
matches. A fourth party, with an unlimited supply of everything, chooses at random a smoker,
and put on the table the supplies needed for a cigarrette. The chosen smoker smokes, and the
process should repeat indefinitely.

package main

import (
"fmt"
"math/rand"
"sync"
"time"
)

const (
paper = iota
grass
match
)

var smokeMap = map[int]string{


paper: "paper",
grass: "grass",
match: "match",
}

var names = map[int]string{


paper: "Sandy",
grass: "Apple",
match: "Daisy",
}

type Table struct {


paper chan int
grass chan int
match chan int
}

func arbitrate(t *Table, smokers [3]chan int) {


for {
time.Sleep(time.Millisecond * 500)
next := rand.Intn(3)
fmt.Printf("Table chooses %s: %s\n", smokeMap[next],
names[next])
switch next {
case paper:
t.grass <- 1
t.match <- 1
case grass:
t.paper <- 1
t.match <- 1
case match:
t.grass <- 1
t.paper <- 1
}
for _, smoker := range smokers {
smoker <- next
}
wg.Add(1)
wg.Wait()
}
}

func smoker(t *Table, name string, smokes int, signal chan int) {
var chosen = -1
for {
chosen = <-signal // blocks

if smokes != chosen {
continue
}

fmt.Printf("Table: %d grass: %d match: %d\n", len(t.paper),


len(t.grass), len(t.match))
select {
case <-t.paper:
case <-t.grass:
case <-t.match:
}
fmt.Printf("Table: %d grass: %d match: %d\n", len(t.paper),
len(t.grass), len(t.match))
time.Sleep(10 * time.Millisecond)
select {
case <-t.paper:
case <-t.grass:
case <-t.match:
}
fmt.Printf("Table: %d grass: %d match: %d\n", len(t.paper),
len(t.grass), len(t.match))
fmt.Printf("%s smokes a cigarette\n", name)
time.Sleep(time.Millisecond * 500)
wg.Done()
time.Sleep(time.Millisecond * 100)
}
}

const LIMIT = 1

var wg *sync.WaitGroup

func main() {
wg = new(sync.WaitGroup)
table := new(Table)
table.match = make(chan int, LIMIT)
table.paper = make(chan int, LIMIT)
table.grass = make(chan int, LIMIT)
var signals [3]chan int
// three smokers
for i := 0; i < 3; i++ {
signal := make(chan int, 1)
signals[i] = signal
go smoker(table, names[i], i, signal)
}
fmt.Printf("%s, %s, %s, sit with \n%s, %s, %s\n\n", names[0],
names[1], names[2], smokeMap[0], smokeMap[1], smokeMap[2])
arbitrate(table, signals)
}
Sandy, Apple, Daisy, sit with
paper, grass, match

Table chooses match: Daisy


Table: 1 grass: 1 match: 0
Table: 1 grass: 0 match: 0
Table: 0 grass: 0 match: 0
Daisy smokes a cigarette
Table chooses paper: Sandy
Table: 0 grass: 1 match: 1
Table: 0 grass: 1 match: 0
Table: 0 grass: 0 match: 0
Sandy smokes a cigarette
Table chooses match: Daisy
Table: 1 grass: 1 match: 0
Table: 1 grass: 0 match: 0
Table: 0 grass: 0 match: 0
Daisy smokes a cigarette

Chapter ..

Logging Go Programs
The standard library package log provides a basic infrastructure for log management in GO
language that can be used for logging our GO programs. The main purpose of logging is to get a
trace of what's happening in the program, where it's happening, and when it's happening. Logs
can be providing code tracing, profiling, and analytics. Logging(eyes and ears of a programmer)
is a way to find those bugs and learn more about how the program is functioning.

To work with package log, we must add it to the list of imports:


import (

"log"

In its simplest usage, it formats messages and sends them to Standard Error check below
example:

// Program in GO language to demonstrates how to use base log package.


package main

import (

"log"

func init(){

log.SetPrefix("LOG: ")

log.SetFlags(log.Ldate | log.Lmicroseconds | log.Llongfile)

log.Println("init started")

func main() {

// Println writes to the standard logger.

log.Println("main started")

// Fatalln is Println() followed by a call to os.Exit(1)

log.Fatalln("fatal message")

// Panicln is Println() followed by a call to panic()

log.Panicln("panic message")

After executing this code, the output would look something like this:

C:\golang>go run example38.go LOG: 2017/06/25 14:49:41.989813


C:/golang/example38.go:11: init started LOG: 2017/06/25 14:49:41.990813
C:/golang/example38.go:15: main started LOG: 2017/06/25 14:49:41.990813
C:/golang/example38.go:18: fatal message exit status 1

Sending messages to Standard Error is useful for simple tools. When we're building servers,
applications, or system services, we need a better place to send your log messages. Here all error
messages are all sent to Standard Error, regardless of whether the message is an actual error or an
informational message.
The standard log entry contains below things:
- a prefix (log.SetPrefix("LOG: "))
- a datetime stamp (log.Ldate)
- full path to the source code file writing to the log (log.Llongfile)
- the line of code performing the write and finally the message.

This pieces of information are automatically generated for us, information about when the event
happened and information about where it happened.

Println is the standard way to write log messages.


Fatalln or any of the other "fatal" calls, the library prints the error message and then calls
os.Exit(1), forcing the program to quit.
Panicln is used to write a log message and then issue a panic which may unless recovered or will
cause the program to terminate.

Program in GO language with real world example of logging.

Now i am taking a real world example and implementing above log package in my program. For
example i am testing an SMTP connection is working fine or not. For test case I am going to
connect to a SMTP server "smtp.smail.com" which is not exist, hence program will terminate
with a log message.

// Program in GO language with real world example of logging.

package main

import (

"log"

"net/smtp"

func init(){

log.SetPrefix("TRACE: ")

log.SetFlags(log.Ldate | log.Lmicroseconds | log.Llongfile)

log.Println("init started")

func main() {

// Connect to the remote SMTP server.


client, err := smtp.Dial("smtp.smail.com:25")

if err != nil {

log.Fatalln(err)

client.Data()

C:\golang>go run example39.go TRACE: 2017/06/25 14:54:42.662011


C:/golang/example39.go:9: init started TRACE: 2017/06/25 14:55:03.685213
C:/golang/example39.go:15: dial tcp 23.27.98.252:25: connectex: A connection attempt failed
because the connected party did not properly respond after a period of time, or established
connection failed because connected host has failed to respond. exit status 1

The above program is throwing fatal exception from log.Fatalln(err).

Chapter ………..

Files and directories with examples


The most important package that allows us to manipulate files and directories as entities is the os
package.
The io package has the io.Reader interface to reads and transfers data from a source into a
stream of bytes. The io.Writer interface reads data from a provided stream of bytes and writes
it as output to a target resource.

Create an empty file


package main

import (
"log"
"os"
)

func main() {
emptyFile, err := os.Create("empty.txt")
if err != nil {
log.Fatal(err)
}
log.Println(emptyFile)
emptyFile.Close()
}
C:\golang\working-with-files>go fmt example1.go C:\golang\working-with-files>golint
example1.go C:\golang\working-with-files>go run example1.go 2018/08/11 15:46:04
&{0xc042060780} C:\golang\working-with-files>

Go program to Create directory or folder if not exist


package main

import (
"log"
"os"
)

func main() {
_, err := os.Stat("test")

if os.IsNotExist(err) {
errDir := os.MkdirAll("test", 0755)
if errDir != nil {
log.Fatal(err)
}

}
}

Rename a file in Golang


package main

import (
"log"
"os"
)

func main() {
oldName := "test.txt"
newName := "testing.txt"
err := os.Rename(oldName, newName)
if err != nil {
log.Fatal(err)
}
}

C:\golang\working-with-files>go fmt example.go C:\golang\working-with-files>golint


example.go C:\golang\working-with-files>go run example.go C:\golang\working-with-files>

Move a file from one location to another in Golang

os.Rename() can also move file from one location to another at same time renaming file name.
package main

import (
"log"
"os"
)

func main() {
oldLocation := "/var/www/html/test.txt"
newLocation := "/var/www/html/src/test.txt"
err := os.Rename(oldLocation, newLocation)
if err != nil {
log.Fatal(err)
}
}

Golang Create Copy of a file at another location


package main

import (
"io"
"log"
"os"
)

func main() {

sourceFile, err := os.Open("/var/www/html/src/test.txt")


if err != nil {
log.Fatal(err)
}
defer sourceFile.Close()

// Create new file


newFile, err := os.Create("/var/www/html/test.txt")
if err != nil {
log.Fatal(err)
}
defer newFile.Close()

bytesCopied, err := io.Copy(newFile, sourceFile)


if err != nil {
log.Fatal(err)
}
log.Printf("Copied %d bytes.", bytesCopied)
}

[root@server src]# clear [root@server src]# go run example6.go 2018/08/15 03:43:39 Copied
100 bytes. [root@server src]#
Get file information in Golang
package main

import (
"fmt"
"log"
"os"
)

func main() {
fileStat, err := os.Stat("test.txt")

if err != nil {
log.Fatal(err)
}

fmt.Println("File Name:", fileStat.Name()) // Base name of the


file
fmt.Println("Size:", fileStat.Size()) // Length in bytes
for regular files
fmt.Println("Permissions:", fileStat.Mode()) // File mode bits
fmt.Println("Last Modified:", fileStat.ModTime()) // Last modification
time
fmt.Println("Is Directory: ", fileStat.IsDir()) // Abbreviation for
Mode().IsDir()
}

C:\golang\working-with-files>go fmt example.go example.go C:\golang\working-with-


files>golint example.go C:\golang\working-with-files>go run example.go File Name: test.txt
Size: 100 Permissions: -rw-rw-rw- Last Modified: 2018-08-11 20:19:14.2671925 +0530 IST Is
Directory: false C:\golang\working-with-files>

Golang program to delete a specific file


package main

import (
"log"
"os"
)

func main() {
err := os.Remove("/var/www/html/test.txt")
if err != nil {
log.Fatal(err)
}
}

Go program to read a text file character by character


package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"strings"
)

func main() {
filename := "test.txt"

filebuffer, err := ioutil.ReadFile(filename)


if err != nil {
fmt.Println(err)
os.Exit(1)
}
inputdata := string(filebuffer)
data := bufio.NewScanner(strings.NewReader(inputdata))
data.Split(bufio.ScanRunes)

for data.Scan() {
fmt.Print(data.Text())
}
}

Reduce file size

os.Truncate() function will reduce the file content upto N bytes passed in second parameter. In
below example if size of test.txt file is more that 1Kb(100 byte) then it will truncate the
remaining content.

package main

import (
"log"
"os"
)

func main() {
err := os.Truncate("test.txt", 100)

if err != nil {
log.Fatal(err)
}
}

C:\golang\working-with-files>go fmt example10.go C:\golang\working-with-files>golint


example10.go C:\golang\working-with-files>go run example10.go C:\golang\working-with-
files>
Go program to add or append content at the end of text file
package main

import (
"fmt"
"os"
)

func main() {
message := "Add this content at end"
filename := "test.txt"

f, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND|os.O_CREATE,


0660)

if err != nil {
fmt.Println(err)
os.Exit(-1)
}
defer f.Close()

fmt.Fprintf(f, "%s\n", message)


}

Golang Changing permissions, ownership, and timestamps


package main

import (
"log"
"os"
"time"
)

func main() {
// Test File existence.
_, err := os.Stat("test.txt")
if err != nil {
if os.IsNotExist(err) {
log.Fatal("File does not exist.")
}
}
log.Println("File exist.")

// Change permissions Linux.


err = os.Chmod("test.txt", 0777)
if err != nil {
log.Println(err)
}

// Change file ownership.


err = os.Chown("test.txt", os.Getuid(), os.Getgid())
if err != nil {
log.Println(err)
}
// Change file timestamps.
addOneDayFromNow := time.Now().Add(24 * time.Hour)
lastAccessTime := addOneDayFromNow
lastModifyTime := addOneDayFromNow
err = os.Chtimes("test.txt", lastAccessTime, lastModifyTime)
if err != nil {
log.Println(err)
}
}

Go program to compress list of files into Zip file


package main

import (
"archive/zip"
"fmt"
"io"
"log"
"os"
)

func appendFiles(filename string, zipw *zip.Writer) error {


file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("Failed to open %s: %s", filename, err)
}
defer file.Close()

wr, err := zipw.Create(filename)


if err != nil {
msg := "Failed to create entry for %s in zip file: %s"
return fmt.Errorf(msg, filename, err)
}

if _, err := io.Copy(wr, file); err != nil {


return fmt.Errorf("Failed to write %s to zip: %s", filename,
err)
}

return nil
}

func main() {
flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC
file, err := os.OpenFile("test.zip", flags, 0644)
if err != nil {
log.Fatalf("Failed to open zip for writing: %s", err)
}
defer file.Close()

var files = []string{"test1.txt", "test2.txt", "test3.txt"}

zipw := zip.NewWriter(file)
defer zipw.Close()
for _, filename := range files {
if err := appendFiles(filename, zipw); err != nil {
log.Fatalf("Failed to add file %s to zip: %s",
filename, err)
}
}
}

Go program to read list of files inside Zip file


package main

import (
"archive/zip"
"fmt"
"log"
"os"
)

func listFiles(file *zip.File) error {


fileread, err := file.Open()
if err != nil {
msg := "Failed to open zip %s for reading: %s"
return fmt.Errorf(msg, file.Name, err)
}
defer fileread.Close()

fmt.Fprintf(os.Stdout, "%s:", file.Name)

if err != nil {
msg := "Failed to read zip %s for reading: %s"
return fmt.Errorf(msg, file.Name, err)
}

fmt.Println()

return nil
}

func main() {
read, err := zip.OpenReader("test.zip")
if err != nil {
msg := "Failed to open: %s"
log.Fatalf(msg, err)
}
defer read.Close()

for _, file := range read.File {


if err := listFiles(file); err != nil {
log.Fatalf("Failed to read %s from zip: %s", file.Name,
err)
}
}
}
Go program to extracting or unzip a Zip format file
package main

import (
"archive/zip"
"io"
"log"
"os"
"path/filepath"
)

func main() {
zipReader, _ := zip.OpenReader("test.zip")
for _, file := range zipReader.Reader.File {

zippedFile, err := file.Open()


if err != nil {
log.Fatal(err)
}
defer zippedFile.Close()

targetDir := "./"
extractedFilePath := filepath.Join(
targetDir,
file.Name,
)

if file.FileInfo().IsDir() {
log.Println("Directory Created:", extractedFilePath)
os.MkdirAll(extractedFilePath, file.Mode())
} else {
log.Println("File extracted:", file.Name)

outputFile, err := os.OpenFile(


extractedFilePath,
os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
file.Mode(),
)
if err != nil {
log.Fatal(err)
}
defer outputFile.Close()

_, err = io.Copy(outputFile, zippedFile)


if err != nil {
log.Fatal(err)
}
}
}
}

Chapter …
Explain the term Cryptography in brief
The term "cryptography" is evolved from two Greek words, namely crypto and graphy. As per
Greek language, crypto means secret and graphy means writing. The term crypto has become
more popular with the introduction of all crypto currencies like Bitcoin, Ethereum, and Litecoin.

What is Cryptography?

In simple terms, the process of altering messages in a way that their meaning is hidden from an
enemy or opponent who might seize them, is known as Cryptography. Cryptography is the
science of secret writing that brings numerous techniques to safeguard information that is present
in an unreadable format. Only the designated recipients can be converted this unreadable format
into the readable format.

In secure electronic transactions, cryptographic techniques are adopted to secure E-mail


messages, credit card details, audio/video broadcasting, storage media and other sensitive
information. By using cryptographic systems, the sender can first encrypt a message and then
pass on it through the network. The receiver on the other hand can decrypt the message and
restore its original content.

Components of Cryptography

Plaintext: Plaintext can be text, binary code, or an image that needs to be converted into a
format that is unreadable by anybody except those who carry the secret to unlocking it. It refers
to the original unencrypted or unadulterated message that the sender wishes to send.

Ciphertext: During the process of encryption plaintext get converted into a rushed format, the
resulting format is called the ciphertext. It relates to the encrypted message, the receiver receives
that. However, ciphertext is like the plaintext that has been operated on by the encryption process
to reproduce a final output. This final output contains the original message though in a format,
that is not retrievable unless official knows the correct means or can crack the code.

Encryption: Encryption, receives information and transforms it to an unreadable format that can
be reversed. It is the process of encrypting the plaintext so it can provide the ciphertext.
Encryption needs an algorithm called a cipher and a secret key. No one can decrypt the vital
information on the encrypted message without knowing the secret key. Plaintext gets
transformed into ciphertext using the encryption cipher.

Decryption: This is the reverse of the encryption process, in which it transforms the ciphertext
back into the plaintext using a decryption algorithm and a secret key. In symmetric encryption,
the key used to decrypt is the same as the key used to encrypt. On other hand, in asymmetric
encryption or public-key encryption the key used to decrypt differs from the key used to encrypt.

Ciphers: The encryption and decryption algorithms are together known as ciphers. Perhaps the
trickiest, interesting and most curious part in the encryption process is the algorithm or cipher.
The algorithm or cipher is nothing more than a formula that comprises various steps that
illustrate how the encryption/decryption process is being implemented on an information. A basic
cipher takes bits and returns bits and it doesn't care whether bits represents textual information,
an image, or a video.

Key: A key is generally a number or a set of numbers on which the cipher operates. In technical
terms, a key is a discrete piece of information that is used to control the output (ciphertext and
plaintext) of a given cryptographic algorithm. Encryption and decryption algorithms needs this
key to encrypt or decrypt messages, respectively. Sender uses the encryption algorithm and the
secret key to convert the plaintext into the ciphertext. On other hand receiver uses same
decryption algorithm and the secret key to convert ciphertext back into the plaintext. The longer
the secret key is, the harder it is for an attacker to decrypt the message.

Example of Cryptography (Classical Cipher)

Below is very basic example, we have created a simple cipher to encrypt and decrypt a plaintext
into ciphertext and vice versa. The algorithm cipherAlgorithm() is same for encryption and
decryption. The key, we have used is 01, 10 and 15 to encrypt and decrypt the message. The
output of encryption is different each time when the key is different. This cipher shifts the letter
based on key value, key plays an important role in cryptography.

package main

import (
"fmt"
"unicode"
)

// Cipher encrypts and decrypts a string.


type Cipher interface {
Encryption(string) string
Decryption(string) string
}

// Cipher holds the key used to encrypts and decrypts messages.


type cipher []int

// cipherAlgorithm encodes a letter based on some function.


func (c cipher) cipherAlgorithm(letters string, shift func(int, int) int)
string {
shiftedText := ""
for _, letter := range letters {
if !unicode.IsLetter(letter) {
continue
}
shiftDist := c[len(shiftedText)%len(c)]
s := shift(int(unicode.ToLower(letter)), shiftDist)
switch {
case s < 'a':
s += 'z' - 'a' + 1
case 'z' < s:
s -= 'z' - 'a' + 1
}
shiftedText += string(s)
}
return shiftedText
}

// Encryption encrypts a message.


func (c *cipher) Encryption(plainText string) string {
return c.cipherAlgorithm(plainText, func(a, b int) int { return a + b })
}

// Decryption decrypts a message.


func (c *cipher) Decryption(cipherText string) string {
return c.cipherAlgorithm(cipherText, func(a, b int) int { return a - b })
}

// NewCaesar creates a new Caesar shift cipher.


func NewCaesar(key int) Cipher {
return NewShift(key)
}
// NewShift creates a new Shift cipher.
func NewShift(shift int) Cipher {
if shift < -25 || 25 < shift || shift == 0 {
return nil
}
c := cipher([]int{shift})
return &c
}

func main() {
c := NewCaesar(1)
fmt.Println("Encrypt Key(01) abcd =>", c.Encryption("abcd"))
fmt.Println("Decrypt Key(01) bcde =>", c.Decryption("bcde"))
fmt.Println()

c = NewCaesar(10)
fmt.Println("Encrypt Key(10) abcd =>", c.Encryption("abcd"))
fmt.Println("Decrypt Key(10) klmn =>", c.Decryption("klmn"))
fmt.Println()

c = NewCaesar(15)
fmt.Println("Encrypt Key(15) abcd =>", c.Encryption("abcd"))
fmt.Println("Decrypt Key(15) pqrs =>", c.Decryption("pqrs"))
}

Output of above
C:\golang\example>go run test8.go
Encrypt Key(01) abcd => bcde
Decrypt Key(01) bcde => abcd

Encrypt Key(10) abcd => klmn


Decrypt Key(10) klmn => abcd

Encrypt Key(15) abcd => pqrs


Decrypt Key(15) pqrs => abcd

C:\golang\example>

Go provides extensive options for cryptography, such as encryption, hashing. Go have packages
to support symmetric encryption algorithms: base64, AES and DES, this we will cover in
coming tutorials.

Chapter …….

Regular Expression (Regex) - Examples and


Solutions
Regular expression (or in short regex) is a very useful tool that is used to describe a search
pattern for matching the text. Regex is nothing but a sequence of some characters that defines a
search pattern. Regex is used for parsing, filtering, validating, and extracting meaningful
information from large text, such as logs and output generated from other programs.
Regular expression to extract text between square brackets
//Regular expression to extract text between square brackets in Golang

package main

import (
"fmt"
"regexp"
"strings"
)

func main() {
str1 := "this is a [sample] [[string]] with [SOME] special words"

re := regexp.MustCompile(`\[([^\[\]]*)\]`)
fmt.Printf("Pattern: %v\n", re.String()) // print pattern
fmt.Println("Matched:", re.MatchString(str1)) // true

fmt.Println("\nText between square brackets:")


submatchall := re.FindAllString(str1, -1)
for _, element := range submatchall {
element = strings.Trim(element, "[")
element = strings.Trim(element, "]")
fmt.Println(element)
}
}
Pattern: \[([^\[\]]*)\]
Matched: true
Text between square brackets:
sample
string
SOME

Regular expression to extract all Non-Alphanumeric Characters from a String


//Regular expression to extract all Non-Alphanumeric Characters from a String

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "We @@@Love@@@@ #Go!$! ****Programming****Language^^^"

re := regexp.MustCompile(`[^a-zA-Z0-9]+`)

fmt.Printf("Pattern: %v\n", re.String()) // print pattern


fmt.Println(re.MatchString(str1)) // true

submatchall := re.FindAllString(str1, -1)


for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: [^a-zA-Z0-9]+
true
@@@
@@@@ #
!$! ****
****
^^^

Regular expression to extract date(YYYY-MM-DD) from string


//Regular expression to extract date(YYYY-MM-DD) from string

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "If I am 20 years 10 months and 14 days old as of August
17,2016 then my DOB would be 1995-10-03"

re := regexp.MustCompile(`\d{4}-\d{2}-\d{2}`)

fmt.Printf("Pattern: %v\n", re.String()) // print pattern

fmt.Println(re.MatchString(str1)) // true

submatchall := re.FindAllString(str1, -1)


for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: \d{4}-\d{2}-\d{2}
true
1995-10-03

Regular expression to extract DNS host-name or IP Address from string


//Regular expression to extract DNS hostname or IP Address from string

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := `Proxy Port Last Check Proxy Speed Proxy Country Anonymity
118.99.81.204
118.99.81.204 8080 34 sec Indonesia - Tangerang Transparent 2.184.31.2
8080 58 sec
Iran Transparent 93.126.11.189 8080 1 min Iran - Esfahan Transparent
202.118.236.130
7777 1 min China - Harbin Transparent 62.201.207.9 8080 1 min Iraq
Transparent`

re := regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`)

fmt.Printf("Pattern: %v\n", re.String()) // print pattern


fmt.Println(re.MatchString(str1)) // true

submatchall := re.FindAllString(str1, -1)


for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?
[0-9][0-9]?)){3}
true
118.99.81.204
118.99.81.204
2.184.31.2
93.126.11.189
202.118.236.130
62.201.207.9

Regular expression to extract domain from URL


//Regular expression to extract domain from URL

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := `http://www.suon.co.uk/product/1/7/3/`

re := regexp.MustCompile(`^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?
([^:\/\n]+)`)
fmt.Printf("Pattern: %v\n", re.String()) // print pattern
fmt.Println(re.MatchString(str1)) // true

submatchall := re.FindAllString(str1,-1)
for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: ^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)
true
http://www.suon.co.uk

Regular expression to validate email address


//Regular expression to validate email address

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "ç$€§/az@gmail.com"
str2 := "abcd@gmail_yahoo.com"
str3 := "abcd@gmail-yahoo.com"
str4 := "abcd@gmailyahoo"
str5 := "abcd@gmail.yahoo"

re := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-
9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-
zA-Z0-9])?)*$")

fmt.Printf("Pattern: %v\n", re.String()) // print pattern


fmt.Printf("\nEmail: %v :%v\n", str1, re.MatchString(str1))
fmt.Printf("Email: %v :%v\n", str2, re.MatchString(str2))
fmt.Printf("Email: %v :%v\n", str3, re.MatchString(str3))
fmt.Printf("Email: %v :%v\n", str4, re.MatchString(str4))
fmt.Printf("Email: %v :%v\n", str5, re.MatchString(str5))
}
Pattern: ^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-
zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

Email: ç$?§/az@gmail.com :false


Email: abcd@gmail_yahoo.com :false
Email: abcd@gmail-yahoo.com :true
Email: abcd@gmailyahoo :true
Email: abcd@gmail.yahoo :true

Regular expression to validate phone number


// Regular expression to validate phone number

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "1(234)5678901x1234"
str2 := "(+351) 282 43 50 50"
str3 := "90191919908"
str4 := "555-8909"
str5 := "001 6867684"
str6 := "001 6867684x1"
str7 := "1 (234) 567-8901"
str8 := "1-234-567-8901 ext1234"

re := regexp.MustCompile(`^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?
[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|
extension|x)[\-\.\ \\\/]?(\d+))?$`)

fmt.Printf("Pattern: %v\n", re.String()) // print pattern


fmt.Printf("\nPhone: %v\t:%v\n", str1, re.MatchString(str1))
fmt.Printf("Phone: %v\t:%v\n", str2, re.MatchString(str2))
fmt.Printf("Phone: %v\t\t:%v\n", str3, re.MatchString(str3))
fmt.Printf("Phone: %v\t\t\t:%v\n", str4, re.MatchString(str4))
fmt.Printf("Phone: %v\t\t:%v\n", str5, re.MatchString(str5))
fmt.Printf("Phone: %v\t\t:%v\n", str6, re.MatchString(str6))
fmt.Printf("Phone: %v\t\t:%v\n", str7, re.MatchString(str7))
fmt.Printf("Phone: %v\t:%v\n", str8, re.MatchString(str8))
}
Pattern: ^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\
(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x
)[\-\.\ \\\/]?(\d+))?$

Phone: 1(234)5678901x1234 :true


Phone: (+351) 282 43 50 50 :true
Phone: 90191919908 :true
Phone: 555-8909 :true
Phone: 001 6867684 :true
Phone: 001 6867684x1 :true
Phone: 1 (234) 567-8901 :true
Phone: 1-234-567-8901 ext1234 :true

Regular expression to validate the date format in "dd/mm/yyyy"


// Regular expression validate the date format in "dd/mm/yyyy"

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "31/07/2010"
str2 := "1/13/2010"
str3 := "29/2/2007"
str4 := "31/08/2010"
str5 := "29/02/200a"
str6 := "29/02/200a"
str7 := "55/02/200a"
str8 := "2_/02/2009"

re := regexp.MustCompile("(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/
((19|20)\\d\\d)")
fmt.Printf("Pattern: %v\n", re.String()) // print pattern
fmt.Printf("\nDate: %v :%v\n", str1, re.MatchString(str1))
fmt.Printf("Date: %v :%v\n", str2, re.MatchString(str2))
fmt.Printf("Date: %v :%v\n", str3, re.MatchString(str3))
fmt.Printf("Date: %v :%v\n", str4, re.MatchString(str4))
fmt.Printf("Date: %v :%v\n", str5, re.MatchString(str5))
fmt.Printf("Date: %v :%v\n", str6, re.MatchString(str6))
fmt.Printf("Date: %v :%v\n", str7, re.MatchString(str7))
fmt.Printf("Date: %v :%v\n", str8, re.MatchString(str8))
}
Pattern: (0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\d\d)
Date: 31/07/2010 :true
Date: 1/13/2010 :false
Date: 29/2/2007 :true
Date: 31/08/2010 :true
Date: 29/02/200a :false
Date: 29/02/200a :false
Date: 55/02/200a :false
Date: 2_/02/2009 :false

Regular expression to validate common Credit Card Numbers


// Regular expression validate Visa, MasterCard, American Express, Diners
Club, Discover, and JCB cards

package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "4111111111111111"
str2 := "346823285239073"
str3 := "370750517718351"
str4 := "4556229836495866"
str5 := "5019717010103742"
str6 := "76009244561"
str7 := "4111-1111-1111-1111"
str8 := "5610591081018250"
str9 := "30569309025904"
str10 := "6011111111111117"

re := regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]
{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]
{11}|(?:2131|1800|35\d{3})\d{11})$`)

fmt.Printf("Pattern: %v\n", re.String()) // print pattern


fmt.Printf("\nCC : %v :%v\n", str1, re.MatchString(str1))
fmt.Printf("CC : %v :%v\n", str2, re.MatchString(str2))
fmt.Printf("CC : %v :%v\n", str3, re.MatchString(str3))
fmt.Printf("CC : %v :%v\n", str4, re.MatchString(str4))
fmt.Printf("CC : %v :%v\n", str5, re.MatchString(str5))
fmt.Printf("CC : %v :%v\n", str6, re.MatchString(str6))
fmt.Printf("CC : %v :%v\n", str7, re.MatchString(str7))
fmt.Printf("CC : %v :%v\n", str8, re.MatchString(str8))
fmt.Printf("CC : %v :%v\n", str9, re.MatchString(str9))
fmt.Printf("CC : %v :%v\n", str10, re.MatchString(str10))
}
Pattern: ^(?:4[0-9]{12}(?:[0-9]{3})?|[25][1-7][0-9]{14}|6(?:011|5[0-9][0-9])
[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|18
00|35\d{3})\d{11})$
CC : 4111111111111111 :true
CC : 346823285239073 :true
CC : 370750517718351 :true
CC : 4556229836495866 :true
CC : 5019717010103742 :false
CC : 76009244561 :false
CC : 4111-1111-1111-1111 :false
CC : 5610591081018250 :true
CC : 30569309025904 :true
CC : 6011111111111117 :true

Replace any non-alphanumeric character sequences with a dash using Regex


package main

import (
"fmt"
"log"
"regexp"
)

func main() {
reg, err := regexp.Compile("[^A-Za-z0-9]+")
if err != nil {
log.Fatal(err)
}
newStr := reg.ReplaceAllString("#Golang#Python$Php&Kotlin@@", "-")
fmt.Println(newStr)
}
-Golang-Python-Php-Kotlin-

Replace first occurrence of string using Regexp


package main

import (
"fmt"
"regexp"
)

func main() {
strEx := "Php-Golang-Php-Python-Php-Kotlin"
reStr := regexp.MustCompile("^(.*?)Php(.*)$")
repStr := "${1}Java$2"
output := reStr.ReplaceAllString(strEx, repStr)
fmt.Println(output)
}
Java-Golang-Php-Python-Php-Kotlin

Regular expression to split string on white spaces


package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "Split String on \nwhite \tspaces."

re := regexp.MustCompile(`\S+`)

fmt.Printf("Pattern: %v\n", re.String()) // Print Pattern

fmt.Printf("String contains any match: %v\n", re.MatchString(str1)) //


True

submatchall := re.FindAllString(str1, -1)


for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: \S+
String contains any match: true
Split
String
on
white
spaces.

Regular expression to extract numbers from a string in Golang


package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "Hello X42 I'm a Y-32.35 string Z30"

re := regexp.MustCompile(`[-]?\d[\d,]*[\.]?[\d{2}]*`)

fmt.Printf("Pattern: %v\n", re.String()) // Print Pattern

fmt.Printf("String contains any match: %v\n", re.MatchString(str1)) //


True

submatchall := re.FindAllString(str1, -1)


for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: [-]?\d[\d,]*[\.]?[\d{2}]*
String contains any match: true
42
-32.35
30

Regular expression to extract filename from given path in Golang


package main

import (
"fmt"
"regexp"
)

func main() {
re := regexp.MustCompile(`^(.*/)?(?:$|(.+?)(?:(\.[^.]*$)|$))`)

str1 := `http://www.golangprograms.com/regular-expressions.html`
match1 := re.FindStringSubmatch(str1)
fmt.Println(match1[2])

str2 := `/home/me/dir3/dir3a/dir3ac/filepat.png`
match2 := re.FindStringSubmatch(str2)
fmt.Println(match2[2])
}
regular-expressions
filepat

Split a string at uppercase letters using regular expression in Golang


package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "Hello X42 I'm a Y-32.35 string Z30"

re := regexp.MustCompile(`[A-Z][^A-Z]*`)

fmt.Printf("Pattern: %v\n", re.String()) // Print Pattern

submatchall := re.FindAllString(str1, -1)


for _, element := range submatchall {
fmt.Println(element)
}
}
Pattern: [A-Z][^A-Z]*
Hello
X42
I'm a
Y-32.35 string
Z30

Regular Expression to get a string between parentheses in Golang


package main

import (
"fmt"
"regexp"
"strings"
)

func main() {
str1 := "This is a (sample) ((string)) with (SOME) special words"

re := regexp.MustCompile(`\((.*?)\)`)
fmt.Printf("Pattern: %v\n", re.String()) // print pattern

fmt.Println("\nText between parentheses:")


submatchall := re.FindAllString(str1, -1)
for _, element := range submatchall {
element = strings.Trim(element, "(")
element = strings.Trim(element, ")")
fmt.Println(element)
}
}
Pattern: \((.*?)\)
Text between parentheses:
sample
string
SOME

How to remove symbols from a string in Golang?


package main

import (
"fmt"
"log"
"regexp"
)

func main() {
str1 := "how much for the maple syrup? $20.99? That's ridiculous!!!"

re, err := regexp.Compile(`[^\w]`)


if err != nil {
log.Fatal(err)
}
str1 = re.ReplaceAllString(str1, " ")
fmt.Println(str1)
}
How much for the apple cider 120 99 It is too much

Regex to extract image name from HTML in Golang


package main

import (
"fmt"
"regexp"
)

func main() {
str1 := `<img src="1.png"><x><z?>
<img czx zcxz src='2.png'><x><z?>`

re := regexp.MustCompile(`<img[^>]+\bsrc=["']([^"']+)["']`)

submatchall := re.FindAllStringSubmatch(str1, -1)


for _, element := range submatchall {
fmt.Println(element[1])
}
}
1.png
2.png

How to replace emoji characters in string using regex in Golang?


package main

import (
"fmt"
"regexp"
)

func main() {
var emojiRx = regexp.MustCompile(`[\x{1F600}-\x{1F6FF}|
[\x{2600}-\x{26FF}]`)
var str = emojiRx.ReplaceAllString("Thats a nice joke 😆😆😆
😛", `[e]`)
fmt.Println(str)
}
Thats a nice joke [e][e][e] [e]

How to extract text from between html tag using Regular Expressions in
Golang?
package main

import (
"fmt"
"regexp"
)

func main() {
str1 := `<html><body>
<form name="query"
action="http://www.example.net/action.php" method="post">
<textarea type="text" name="nameiknow">The text
I want</textarea>
<div id="button">
<input type="submit" value="Submit" />
</div>
</form>
</body></html>`

re := regexp.MustCompile(`<textarea.*?>(.*)</textarea>`)

submatchall := re.FindAllStringSubmatch(str1, -1)


for _, element := range submatchall {
fmt.Println(element[1])
}
}
The text I want

Regular expression for matching HH:MM time format in Golang


package main

import (
"fmt"
"regexp"
)

func main() {
str1 := "8:2"
str2 := "9:9"
str3 := "12:29"
str4 := "02:5"
str5 := "23:59"
str6 := "55:59"
str7 := "0:01"

re := regexp.MustCompile(`^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5]
[0-9])$`)

fmt.Printf("Pattern: %v\n", re.String()) // print pattern


fmt.Printf("Time: %v\t:%v\n", str1, re.MatchString(str1))
fmt.Printf("Time: %v\t:%v\n", str2, re.MatchString(str2))
fmt.Printf("Time: %v\t:%v\n", str3, re.MatchString(str3))
fmt.Printf("Time: %v\t:%v\n", str4, re.MatchString(str4))
fmt.Printf("Time: %v\t:%v\n", str5, re.MatchString(str5))
fmt.Printf("Time: %v\t:%v\n", str6, re.MatchString(str6))
fmt.Printf("Time: %v\t:%v\n", str7, re.MatchString(str7))
}
Pattern: ^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9])$
Time: 8:2 :true
Time: 9:9 :true
Time: 12:29 :true
Time: 02:5 :true
Time: 23:59 :true
Time: 55:59 :false
Time: 0:01 :true

Chapter ….

Example of Golang CRUD using MySQL


from scratch
In this tutorial, we are going to see an example program to learn how to do database CRUD operations
using Golang and MySQL. CRUD is an acronym for Create, Read, Update, and Delete. CRUD operations
are basic data manipulation for database.

In this example, we are going to create an interface as database front end to handle these operations.
We have Employee table containing Employee information like id, name and city. With this table, we
have to perform CRUD using MySQL.

Step 1: Prepare and Import MySQL driver into your project

Using Git Bash first install driver for Go's MySQL database package. Run below command and
install MySQL driver's

go get -u github.com/go-sql-driver/mysql

Now create Goblog Database

1. Open PHPMyAdmin/SQLyog or what ever MySQL database management tool that you are
using.
2. Create a new database "goblog"

Step 2: Creating the Employee Table

Execute the following SQL query to create a table named Employee inside your MySQL
database. We will use this table for all of our future operations.

DROP TABLE IF EXISTS `employee`;


CREATE TABLE `employee` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`city` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Step 3: Creating Struct, Handler and Handler Function

Let's create a file named main.go and put the following code inside it.
We usually import database/sql and use sql to execute database queries on the database.
Function dbConn opens connection with MySQL driver.
We will create Employee struct that has following properties: Id, Name and City.

package main

import (
"database/sql"
"log"
"net/http"
"text/template"

_ "github.com/go-sql-driver/mysql"
)

type Employee struct {


Id int
Name string
City string
}

func dbConn() (db *sql.DB) {


dbDriver := "mysql"
dbUser := "root"
dbPass := "root"
dbName := "goblog"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
if err != nil {
panic(err.Error())
}
return db
}

var tmpl = template.Must(template.ParseGlob("form/*"))

func Index(w http.ResponseWriter, r *http.Request) {


db := dbConn()
selDB, err := db.Query("SELECT * FROM Employee ORDER BY id DESC")
if err != nil {
panic(err.Error())
}
emp := Employee{}
res := []Employee{}
for selDB.Next() {
var id int
var name, city string
err = selDB.Scan(&id, &name, &city)
if err != nil {
panic(err.Error())
}
emp.Id = id
emp.Name = name
emp.City = city
res = append(res, emp)
}
tmpl.ExecuteTemplate(w, "Index", res)
defer db.Close()
}

func Show(w http.ResponseWriter, r *http.Request) {


db := dbConn()
nId := r.URL.Query().Get("id")
selDB, err := db.Query("SELECT * FROM Employee WHERE id=?", nId)
if err != nil {
panic(err.Error())
}
emp := Employee{}
for selDB.Next() {
var id int
var name, city string
err = selDB.Scan(&id, &name, &city)
if err != nil {
panic(err.Error())
}
emp.Id = id
emp.Name = name
emp.City = city
}
tmpl.ExecuteTemplate(w, "Show", emp)
defer db.Close()
}

func New(w http.ResponseWriter, r *http.Request) {


tmpl.ExecuteTemplate(w, "New", nil)
}

func Edit(w http.ResponseWriter, r *http.Request) {


db := dbConn()
nId := r.URL.Query().Get("id")
selDB, err := db.Query("SELECT * FROM Employee WHERE id=?", nId)
if err != nil {
panic(err.Error())
}
emp := Employee{}
for selDB.Next() {
var id int
var name, city string
err = selDB.Scan(&id, &name, &city)
if err != nil {
panic(err.Error())
}
emp.Id = id
emp.Name = name
emp.City = city
}
tmpl.ExecuteTemplate(w, "Edit", emp)
defer db.Close()
}

func Insert(w http.ResponseWriter, r *http.Request) {


db := dbConn()
if r.Method == "POST" {
name := r.FormValue("name")
city := r.FormValue("city")
insForm, err := db.Prepare("INSERT INTO Employee(name, city)
VALUES(?,?)")
if err != nil {
panic(err.Error())
}
insForm.Exec(name, city)
log.Println("INSERT: Name: " + name + " | City: " + city)
}
defer db.Close()
http.Redirect(w, r, "/", 301)
}

func Update(w http.ResponseWriter, r *http.Request) {


db := dbConn()
if r.Method == "POST" {
name := r.FormValue("name")
city := r.FormValue("city")
id := r.FormValue("uid")
insForm, err := db.Prepare("UPDATE Employee SET name=?, city=? WHERE
id=?")
if err != nil {
panic(err.Error())
}
insForm.Exec(name, city, id)
log.Println("UPDATE: Name: " + name + " | City: " + city)
}
defer db.Close()
http.Redirect(w, r, "/", 301)
}

func Delete(w http.ResponseWriter, r *http.Request) {


db := dbConn()
emp := r.URL.Query().Get("id")
delForm, err := db.Prepare("DELETE FROM Employee WHERE id=?")
if err != nil {
panic(err.Error())
}
delForm.Exec(emp)
log.Println("DELETE")
defer db.Close()
http.Redirect(w, r, "/", 301)
}

func main() {
log.Println("Server started on: http://localhost:8080")
http.HandleFunc("/", Index)
http.HandleFunc("/show", Show)
http.HandleFunc("/new", New)
http.HandleFunc("/edit", Edit)
http.HandleFunc("/insert", Insert)
http.HandleFunc("/update", Update)
http.HandleFunc("/delete", Delete)
http.ListenAndServe(":8080", nil)
}

Step 4: Creating Template files

Now it's time to build the Template files of our CRUD application. Create form folder at same
location where we have created main.go.

a) Let's create a file named Index.tmpl inside the form folder and put the following code inside
it.

{{ define "Index" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2> Registered </h2>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>City</td>
<td>View</td>
<td>Edit</td>
<td>Delete</td>
</tr>
</thead>
<tbody>
{{ range . }}
<tr>
<td>{{ .Id }}</td>
<td> {{ .Name }} </td>
<td>{{ .City }} </td>
<td><a href="/show?id={{ .Id }}">View</a></td>
<td><a href="/edit?id={{ .Id }}">Edit</a></td>
<td><a href="/delete?id={{ .Id }}">Delete</a><td>
</tr>
{{ end }}
</tbody>
</table>
{{ template "Footer" }}
{{ end }}

b) Now create another file named Header.tmpl inside the same form folder and put the
following code inside it.

{{ define "Header" }}
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Golang Mysql Curd Example</title>
<meta charset="UTF-8" />
</head>
<body>
<h1>Golang Mysql Curd Example</h1>
{{ end }}

c) Now create another file named Footer.tmpl inside the same form folder and put the
following code inside it.

{{ define "Footer" }}
</body>
</html>
{{ end }}

d) Now create another file named Menu.tmpl inside the same form folder and put the following
code inside it.

{{ define "Menu" }}
<a href="/">HOME</a> |
<a href="/new">NEW</a>
{{ end }}

e) Next, we have to create Show.tmpl file for item details page, so again create this file in form
folder.

{{ define "Show" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2> Register {{ .Id }} </h2>
<p>Name: {{ .Name }}</p>
<p>City: {{ .City }}</p><br /> <a href="/edit?id={{
.Id }}">Edit</a></p>
{{ template "Footer" }}
{{ end }}

f) Now we create new blade file for create new item, it's call New.tmpl file inside form.

{{ define "New" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2>New Name and City</h2>
<form method="POST" action="insert">
<label> Name </label><input type="text" name="name" /><br />
<label> City </label><input type="text" name="city" /><br />
<input type="submit" value="Save user" />
</form>
{{ template "Footer" }}
{{ end }}

g) At last, we need to create Edit.tmpl file for update item, so again create this file in form
folder.

{{ define "Edit" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2>Edit Name and City</h2>
<form method="POST" action="update">
<input type="hidden" name="uid" value="{{ .Id }}" />
<label> Name </label><input type="text" name="name" value="{{ .Name }}"
/><br />
<label> City </label><input type="text" name="city" value="{{ .City }}"
/><br />
<input type="submit" value="Save user" />
</form><br />
{{ template "Footer" }}
{{ end }}

After a long journey finally we've created all files of our CRUD application with Golang and MySQL.
Run the following command

go run main.go

Load the following URL

http://localhost:8080/
Chapter …

Design philosophy of Golang interface type


Implementing a Go interface is done implicitly. In Go, there is no need to explicitly implement
an interface into a concrete type by specifying any keyword. To implement an interface into a
concrete type, just provide the methods with the same signature that is defined in the interface
type.

An interface type is defined with the keyword interface. An interface defines a set of methods
(the method set), but these methods do not contain code: they are not implemented (they are
abstract). A method set is a list of methods that a type must have in order to implement the
interface. Also an interface cannot contain variables.

An interface is declared in the format


Interface Type catalog

type catalog interface {

shipping() float64

tax() float64

The interface type catalog is a contract for creating various product types in a catalog. The
catalog interface provides two behaviors in its contract: shipping and tax.
Implementing an interface

The following source code shows the configurable type as an implementation of the interface
type catalog. The configurable type is defined as a struct with receiver methods shipping and tax.
This fact automatically qualifies configurable as an implementation of catalog:

package main

import "fmt"

type catalog interface {

shipping() float64

tax() float64

type configurable struct {

name string

price, qty float64

func (c *configurable) tax() float64{

return c.price * c.qty * 0.05

func (c *configurable) shipping() float64{

return c.qty * 5

func main() {

tshirt := configurable{}
tshirt.price = 250

tshirt.qty = 2

fmt.Println("Shipping Charge: ", tshirt.shipping())

fmt.Println("Tax: ", tshirt.tax())

When you run the program, you get the following output:
C:\golang>go run example.go
Shipping Charge: 10
Tax: 25

Subtyping with Go interfaces

Go support composition (has-a) relationships when building objects using subtyping via
interfaces. This can be explained that the configurable, download, simple type (and any other
type that implements the methods shipping and tax) can be treated as a subtype of catalog, as
shown in the following figure:
package main

import "fmt"

type catalog interface {

shipping() float64

tax() float64

type configurable struct {

name string

price, qty float64

func (c *configurable) tax() float64{

return c.price * c.qty * 0.05

func (c *configurable) shipping() float64{

return c.qty * 5

type download struct{

name string

price, qty float64

func (d *download) tax() float64{


return d.price * d.qty * 0.07

type simple struct {

name string

price, qty float64

func (s *simple) tax() float64{

return s.price * s.qty * 0.03

func (s *simple) shipping() float64{

return s.qty * 3

func main() {

tshirt := configurable{}

tshirt.price = 250

tshirt.qty = 2

fmt.Println("Configurable Product")

fmt.Println("Shipping Charge: ", tshirt.shipping())

fmt.Println("Tax: ", tshirt.tax())

mobile := simple{"Samsung S-7",10,25}

fmt.Println("\nSimple Product")

fmt.Println("Shipping Charge: ", mobile.shipping())


fmt.Println("Tax: ", mobile.tax())

book := download{"Python in 24 Hours",19,1}

fmt.Println("\nDownloadable Product")

fmt.Println("Tax: ", book.tax())

When you run the program, you get the following output:
C:\golang>go run example.go
Configurable Product
Shipping Charge: 10
Tax: 25

Simple Product
Shipping Charge: 75
Tax: 7.5

Downloadable Product
Tax: 1.33

C:\golang>

Multiple interfaces

In GO, the implicit mechanism of interfaces allows to satisfy multiple interface type at once.
This can be implemented by intergrating the method set of a given type intersect with the
methods of each interface type. Let us re-implement the previous code. New interface discount
has been created. This is illustrated by the following figure:
package main

import "fmt"

type catalog interface {

shipping() float64

tax() float64

}
type discount interface{

offer() float64

type configurable struct {

name string

price, qty float64

func (c *configurable) tax() float64{

return c.price * c.qty * 0.05

func (c *configurable) shipping() float64{

return c.qty * 5

func (c *configurable) offer() float64{

return c.price * 0.15

type download struct{

name string

price, qty float64

}
func (d *download) tax() float64{

return d.price * d.qty * 0.10

type simple struct {

name string

price, qty float64

func (s *simple) tax() float64{

return s.price * s.qty * 0.03

func (s *simple) shipping() float64{

return s.qty * 3

func (s *simple) offer() float64{

return s.price * 0.10

func main() {

tshirt := configurable{}

tshirt.price = 250

tshirt.qty = 2

fmt.Println("Configurable Product")

fmt.Println("Shipping Charge: ", tshirt.shipping())


fmt.Println("Tax: ", tshirt.tax())

fmt.Println("Discount: ", tshirt.offer())

mobile := simple{"Samsung S-7",3000,2}

fmt.Println("\nSimple Product")

fmt.Println(mobile.name)

fmt.Println("Shipping Charge: ", mobile.shipping())

fmt.Println("Tax: ", mobile.tax())

fmt.Println("Discount: ", mobile.offer())

book := download{"Python in 24 Hours",50,1}

fmt.Println("\nDownloadable Product")

fmt.Println(book.name)

fmt.Println("Tax: ", book.tax())

When you run the program, you get the following output:
C:\golang>go run example.go
Configurable Product
Shipping Charge: 10
Tax: 25
Discount: 37.5

Simple Product
Samsung S-7
Shipping Charge: 6
Tax: 180
Discount: 300

Downloadable Product
Python in 24 Hours
Tax: 5

C:\golang>
Interface embedding

In GO, the interface type also support for type embedding (similar to the struct type). This gives
you the flexibility to structure your types in ways that maximize type reuse.
Continuing with the catalog example, a struct configurable is declared in which the type discount
and giftpack is embedded. Here you create more concrete types of the catalog interface. Because
type giftpack and discount is an implementation of the catalog interface, the type configurable is
also an implementation of the catalog interface. All fields and methods defined in the Type
discount and giftpack types are also available in the configurable type.
The following illustration shows how the interface types may be combined so the is-a
relationship still satisfies the relationships between code components:
package main

import "fmt"

type discount interface{

offer() float64

type giftpack interface{

available() string

type catalog interface {

discount

giftpack

shipping() float64

tax() float64

type configurable struct {

name string

price, qty float64

func (c *configurable) tax() float64{

return c.price * c.qty * 0.05

}
func (c *configurable) shipping() float64{

return c.qty * 5

func (c *configurable) offer() float64{

return c.price * 0.15

func (c *configurable) available() string{

if c.price > 1000{

return "Gift Pack Available"

return "Gift Pack not Available"

type download struct{

name string

price, qty float64

func (d *download) tax() float64{

return d.price * d.qty * 0.10

func (d *download) available() string{

if d.price > 500{

return "Gift Pack Available"


}

return "Gift Pack not Available"

type simple struct {

name string

price, qty float64

func (s *simple) tax() float64{

return s.price * s.qty * 0.03

func (s *simple) shipping() float64{

return s.qty * 3

func (s *simple) offer() float64{

return s.price * 0.10

func main() {

tshirt := configurable{}

tshirt.price = 1550

tshirt.qty = 2

fmt.Println("Configurable Product")

fmt.Println("Shipping Charge: ", tshirt.shipping())


fmt.Println("Tax: ", tshirt.tax())

fmt.Println("Discount: ", tshirt.offer())

fmt.Println(tshirt.available())

mobile := simple{"Samsung S-7",3000,2}

fmt.Println("\nSimple Product")

fmt.Println(mobile.name)

fmt.Println("Shipping Charge: ", mobile.shipping())

fmt.Println("Tax: ", mobile.tax())

fmt.Println("Discount: ", mobile.offer())

book := download{"Python in 24 Hours",50,1}

fmt.Println("\nDownloadable Product")

fmt.Println(book.name)

fmt.Println("Tax: ", book.tax())

fmt.Println(book.available())

When you run the program, you get the following output:
C:\golang>go run example.go
Configurable Product
Shipping Charge: 10
Tax: 155
Discount: 232.5
Gift Pack Available

Simple Product
Samsung S-7
Shipping Charge: 6
Tax: 180
Discount: 300

Downloadable Product
Python in 24 Hours
Tax: 5
Gift Pack not Available

C:\golang>

S-ar putea să vă placă și