Table of Content
- Hello World
- Variables
- Constants
- For
- If/Else
- Switch
- Arrays
- Maps
- Slices
- Functions
- Pointers
- Structs
- Goroutines & WaitGroups
- Building a CRUD API
What is Go ?
Go is an open-sourced programming language that was first published in 2009 and developed by Google’s Rob Pike, Robert Griesemer, and Ken Thompson. Based on the syntax of C, it comes with some changes and improvements to safely manage memory usage, manage objects, and provide static or strict typing along with concurrency.
Go was created with the goal of:
- The simplicity of use while increasing productivity
- Providing a high level of code efficiency
- Advanced performance for businesses.
Tutorials
Hello World
Our first program will print the classic “hello world” message. Here’s the source code.
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
To run a go program , create a file named hello-world.go and use go run .
To build our programs into binaries just use go build .
Variables
var declares a variable value
You can Declare multiple variables at once . Variable value can be changed , := syntax is shorthand for declaring and initializing a variable like var name string ="golang"
Note- you have to use every variable you declared , that's the beauty of golang
package main
import "fmt"
func main() {
var name="golang"
fmt.Println(name)
var fruit string="Apple"
fmt.Println(fruit)
var age=10
fmt.Println(age)
var day int=2
fmt.Println(day)
week:=4
fmt.Println(week)
var flag bool =true
fmt.Println(flag)
}
Output -
Constants
const declare a constant value
You cannot change value of const variable , you have to declare and initialization at the same time .
package main
import "fmt"
func main() {
const pi=3.14
fmt.Println(pi)
}
For
In golang we only have for loop , which is enough . A for loop without any condition is just like while(true) , you can use break or return to get out of this loop.
package main
import "fmt"
func main() {
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
}
for j := 7; j <= 9; j++ {
if j==8 {
continue
}
fmt.Println(j)
}
for { // Infinite Loop
fmt.Println("loop")
break
}
}
If/Else
You can use if with out else .
To branch multiple condition you can use if ... else if ... else.
Here’s a basic example.
package main
import "fmt"
func main() {
i :=10
if i<10 {
fmt.Println("Number entered is one digit only")
}else if i>10 &&i<99{
fmt.Println("Number entered is two digit only")
}else{
fmt.Println("Number entered is more than two digit only")
}
}
Switch
Switch statements express conditionals across many branches.
You can use commas to separate multiple expressions in the same case statement. We use the optional default case in this example as well.
Here’s a basic switch.
package main
import "fmt"
func main(){
cityName := "Newyork"
switch cityName {
case "Newyork" :
fmt.Println("It is beautiful")
case "Berlin","London": // mulitple condition
fmt.Println("It is great people living")
default:
fmt.Println("no city")
}
}
Arrays
In Go, an array is a numbered sequence of elements of a fixed length.
The builtin len returns the length of an array.
Array types are one-dimensional, but you can compose types to build multi-dimensional data structures.
package main
import "fmt"
func main(){
var bookings = [3]string{} //
// var bookings [50]string // alternative way
bookings[0]="John"
var len=len(bookings) // length of array
fmt.Printf("Array %v of length %v",bookings ,len) // print whole array
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2D : ",twoD)
}
Output -
Maps
Maps are Go’s built-in associative data type (sometimes called hashes or dicts in other languages).
The builtin len returns the number of key/value pairs when called on a map.
To create an empty map, use the builtin make: make(map[key-type]val-type).
Set key/value pairs using typical name[key] = val syntax.
The builtin delete removes key/value pairs from a map.
package main
import (
"fmt"
)
// 1. Unique keys to values
// 2. You can retrieve the value with the key
func main(){
var userData=make(map[string]string) // [type]type
userData["FirstName"]="John"
userData["LastName"]="Cena"
userData["email"]="john@cena.com"
fmt.Printf("Map %v of length %v \n",userData,len(userData))
}
Slices
Slices are a key data type in Go, giving a more powerful interface to sequences than arrays. In slices we don't have to specify the length i.e. Dynamic in length .
Here is a basics example
package main
import (
"fmt"
)
func main(){
var names []string // s:=make([]string,3) with a specified length
names =append(names,"john")
names=append(names,"ben")
names=append(names, "harry")
l:=names[1:]
fmt.Println("Slice ",names)
fmt.Printf("SubList of name is %v",l)
}
Functions
Functions are central in Go, you can return single as well as multiple values in Golang .
Here's is a basic examples of functions
package main
import "fmt"
func equal(a int,b int) bool{ //Return a single value
return a==b
}
func bodmas(a int , b int) (int,int,int) { // Return multiple values
sums:=a+b
min:=a-b
mul:=a*b
return sums ,min ,mul
}
func main(){
isequal:=equal(10,10)
fmt.Println(isequal)
a,b,c:=bodmas(20,10)
fmt.Println(a,b,c);
}
Pointers
Golang supports pointers , allowing you to pass references to values . Here &val is memory address of that variable .
Pointers can be printed too.
package main
import "fmt"
func change(val int){
val=0
}
func changePtr(val *int){
*val=0
}
func main(){
val:=1
fmt.Printf("initial %v\n",val)
change(val)
fmt.Printf("after function change %v \n",val)
changePtr(&val)
fmt.Printf("after function changePtr %v",val)
}
Structs
A struct in Golang is a user-defined type that allows to group/combine items of possibly different types into a single type.
Here UserData struct type has firstName, lastName, age, dob fields of different datatype .
type UserData struct{
firstName string
lastName string
age uint
dob string
}
The above syntax creates a new struct . This concept is similar to classes in object-oriented-programming .
user1:=UserData{firstName:"John",lastName:"Cena",age:45 ,dob: "MM/DD/YYYY" }
name:=user1.firstName // to access the fields
Here is a basic implementation -
package main
import "fmt"
// Mixed data type
type UserData struct{
firstName string
lastName string
age uint
dob string
}
var bookings=make([]UserData,0) // array of Userdata type
func main(){
bookings = append(bookings, UserData{firstName:"John",lastName:"Cena",age:45 ,dob: "MM/DD/YYYY" })
fmt.Println(bookings)
fmt.Printf(" Name : %v %v \n Age : %v \n DOB : %v ",bookings[0].firstName,bookings[0].lastName,bookings[0].age,bookings[0].dob)
}
Goroutines & WaitGroups
A goroutine is a lightweight thread of execution.
GO keyword
1) Create a separate thread , just like async i.e. code written still works while that thread is executing , If we don't use go keyword then the code will execute that function & then move on to rest statement .
2) go start a new goroutine
A goroutine is a lightweight thread managed
by go runtime
3) Faster and Stay Responsive
Wait Group
1) Wait for the launched goroutine to finish
2) Package "sync" provides basic synchronization functionality
3) Add() - Sets the number go routines to wait for
4) Wait() - Blocks until the wait group counter is 0
5) Done() - Decrement the wait group counter by 1 , So this is called by the goroutine to indicate that it's finished .
package main
import (
"fmt"
"time"
"sync"
)
var wg=sync.WaitGroup{};
func sleep(){
time.Sleep(2*time.Second)
fmt.Println("Done ..")
wg.Done()
}
func main(){
wg.Add(1)
fmt.Println("Going......")
go sleep()
wg.Wait()
}
CRUD API
Now we have learnt basic concepts of golang and now we can implement our learning by creating a CRUD api and test the api in Postman .
1) Create a struct Student and Principle .
type Student struct{
Rollno string `json:"rollno"`
Name string `json:"name"`
Class string `json:"class"`
Principle *Principle `json:"principle"`
}
type Principle struct{
Name string `json:"name"`
}
2) Handle the Get Request
func getstudents(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(students)
}
3) Handle the delete Request
func deleteStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
param := mux.Vars(r)
for index, item := range students {
if item.Rollno == param["rollno"] {
students = append(students[:index], students[index+1:]...)
break
}
}
json.NewEncoder(w).Encode(students)
}
4) Create a new student
func createStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var student Student
_ = json.NewDecoder(r.Body).Decode(&student)
student.Rollno = strconv.Itoa(rand.Intn(100000))
students = append(students, student)
json.NewEncoder(w).Encode(student)
}
5) Update a Particular students -
func updateStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
params := mux.Vars(r)
for index, item := range students {
if item.Rollno == params["rollno"] {
students = append(students[:index], students[index+1:]...)
var student Student
_ = json.NewDecoder(r.Body).Decode(&student)
student.Rollno = params["rollno"]
students = append(students, student)
json.NewEncoder(w).Encode(student)
}
}
}
6) Get a student details with a rollno
func getStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
param := mux.Vars(r)
for _, item := range students {
if item.Rollno == param["rollno"] {
json.NewEncoder(w).Encode(item)
return
}
}
}
Here is the full code .
package main
import (
"encoding/json"
"fmt"
"log"
"math/rand"
"net/http"
"strconv"
"github.com/gorilla/mux"
)
type Student struct {
Rollno string `json:"rollno"`
Name string `json:"name"`
Class string `json:"class"`
Principle *Principle `json:"principle"`
}
type Principle struct {
Name string `json:"name"`
}
var students []Student
func getstudents(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(students)
}
func deleteStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
param := mux.Vars(r)
for index, item := range students {
if item.Rollno == param["rollno"] {
students = append(students[:index], students[index+1:]...)
break
}
}
json.NewEncoder(w).Encode(students)
}
func createStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var student Student
_ = json.NewDecoder(r.Body).Decode(&student)
student.Rollno = strconv.Itoa(rand.Intn(100000))
students = append(students, student)
json.NewEncoder(w).Encode(student)
}
func updateStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
params := mux.Vars(r)
for index, item := range students {
if item.Rollno == params["rollno"] {
students = append(students[:index], students[index+1:]...)
var student Student
_ = json.NewDecoder(r.Body).Decode(&student)
student.Rollno = params["rollno"]
students = append(students, student)
json.NewEncoder(w).Encode(student)
}
}
}
func getStudent(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
param := mux.Vars(r)
for _, item := range students {
if item.Rollno == param["rollno"] {
json.NewEncoder(w).Encode(item)
return
}
}
}
func main() {
r := mux.NewRouter()
students = append(students, Student{Rollno: "1", Name: "Harry", Class: "10", Principle: &Principle{Name: "John Clarks"}})
students = append(students, Student{Rollno: "2", Name: "Mandy", Class: "9", Principle: &Principle{Name: "Shawn Medes"}})
r.HandleFunc("/", getstudents).Methods("GET")
r.HandleFunc("/students/{id}", getStudent).Methods("GET")
r.HandleFunc("/students", createStudent).Methods("POST")
r.HandleFunc("/students/{id}", updateStudent).Methods("POST")
r.HandleFunc("/students/{id}", deleteStudent).Methods("DELETE")
fmt.Printf("Starting server at port 8000")
log.Fatal(http.ListenAndServe(":8000", r))
}
You can use PostMan to test Api End points .
Resources to learn More about golang -
1) Golang docs for api
2) Freecodecamp GoLang Tutorial
Connect with here ❤️ -
Twitter
Top comments (2)
I have a dumb question? Does it necessary to learn GoLang for DevOps career? I'm still a college student.
Most of the cncf project are built with Golang hence you can easily contribute to those project .