Here I will be putting some snippets using Golang, for you to try or explore or use.
Just copy the files in your workspace & check the results, I have added some comments also which may help you to understand the code. Will suggest to copy the below code in eclipse or your favorite IDE which you have configured for Go, to undertand it better & try. I am not pasting the output, but first copy the code & execute the 'Second.go', i.e. the code having package main which is using all other files given before it & having package first
Before trying the below code make sure either you have good idea about Go or have gone through the tutorial here.
If get any issue with the below code then please let me know.
Just copy the files in your workspace & check the results, I have added some comments also which may help you to understand the code. Will suggest to copy the below code in eclipse or your favorite IDE which you have configured for Go, to undertand it better & try. I am not pasting the output, but first copy the code & execute the 'Second.go', i.e. the code having package main which is using all other files given before it & having package first
Before trying the below code make sure either you have good idea about Go or have gone through the tutorial here.
If get any issue with the below code then please let me know.
package first
import (
"fmt"
// "math"
"strconv"
)
var unused1 string = "unused1"
// unused2 := "unused2"
var FirstName string = "Nitin"
func Method1() {
lastName := "Agrawala"
n := 2
var k uint64 = 78
// var unused3 string = "unused3"
// unused4 := "unused4"
// l := 79
fmt.Printf("%T", k)
// fmt.Println(l-k)
// fmt.Println(unused2)
fmt.Println(string(n))
fmt.Println(strconv.Itoa(n))
fmt.Printf("Hello %v %v %T\n", FirstName, lastName, FirstName)
fmt.Println(10 &^ 3)
var fl float32 = 3.14
fl = 1.2e8
fmt.Printf("%v %T\n", fl, fl)
str := "Nitin Agrawal"
b := []byte(str)
b[3] = 111
fmt.Println(string(b))
fmt.Println(str)
FileSize()
}
func Another() {
fmt.Println("In another()......")
fmt.Println(FirstName)
const a = 4 // make var to const & it will work as during compilation 'a' with its value in the expression to do implicit type conversion
var b int32 = 5
fmt.Println(a + b)
const (
y = iota // it will have 0 as value as it is first element in the tuple
x = true
h // though h is not given any value but still it will get the value as given to its previous
// variable i.e. true here.
z = iota // it will have 3 as value as it is fourth element in the tuple
s = "default"
e // similar to h above it will get the same as given to s above
_ = iota + 2 // _ is used here just to dump the current iota value, so that l below can get next value
l
)
fmt.Printf("%v %v %v\n", x, y, z)
fmt.Printf("%v %v\n", h, e)
fmt.Println(l)
const f = iota
const g = iota
fmt.Printf("%v %v\n", f, g) // here both get 0 as value as both are independent
}
func FileSize() {
const (
B = 1
KB = B * 1024
MB = KB * 1024
GB = MB * 1024
TB = GB * 1024
)
// filesSize := 400000000
fmt.Printf("File Size in GBs : %.2f\n", 400000000.0/GB)
// fmt.Printf("%.2f\n", 12.0/11)
s := [3]int{1, 2, 3}
t := s // Here a complete new copy of 's' is created
t[1] = 4 // it will change the data of t only & not of s
fmt.Println("Original : ", s)
fmt.Println("Copy : ", t)
u := []int{1, 2, 3, 4, 5, 6, 7, 8} //this is how you define a slice, you can use [...] also instead of [], so u is a projection of the array here.
v := u[3:6] // here v is another projection on the array being pointed by u
v[1] = 10
fmt.Println("Original : ", u)
fmt.Println("Copy : ", v)
fmt.Println(len("Nitin"))
fmt.Println(len(u))
}
===============================================================================================
package first
import (
"fmt"
)
func Maps(name, when string, value int) string { // you can can combine similar type of parameters together & say their type only once like shown here
// As shown, one can mention the return type to return
names := map[string]int{
"Ajay": 30,
"Sumit": 28,
"Yasir": 35,
"Sudhir": 27,
name: value,
}
for name, age := range names {
fmt.Printf("%v : %v\n", name, age)
}
return "Done wth map........." // returning the string type of data as mentioned in function signature above
}
===============================================================================================
package first
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func Logging(site string) {
a := "start"
defer fmt.Println("Value of a : ", a) // Check the value of a printed, though it is deferred but its value is processed already which will be used later
// panic("Panic happened............") // If you uncomment this statement then whole application will terminate when this statement is executed
// Also note that, before panic is executed defered statements will be executed first.
// here defer
a = "end"
panicer() // Notice, panic terminates the function it is called from, thats why panic() is called from other function keeping this function
// in running state
fmt.Println("Return from panicer()....")
res, err := http.Get(site)
if err != nil {
fmt.Println(err)
log.Fatal(err)
}
defer res.Body.Close() // If you remove defer then you will get the error as response is closed before it is read in next line
// You can use this way to close this response or connection as soon you open it, not to forget later to close it but defer it.
// But be careful while you are opening the connections in some & you need those connections for that loop only, then use defer
// else you will be make lot of connections open which later can cause the issue.
robots, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
log.Fatal(err)
}
fmt.Printf("Content : %s\n", string(robots[50])) // if you dont use %s then you will get the list of Ascii codes only
}
func panicer() {
fmt.Println("In panicer()......")
defer func() { // this anonymous function & is executed immediately
if err := recover(); err != nil { // using recover(), one can recover from the first panic generated from outside & recover() works only when used from defer func(), as after panic()
// runtime will not execute any more statements but execute the defer statements.
log.Println(err)
// panic(err) //uncomment this then it will terminate the main() method, as we rethrowing the error if it can't be handled to continue
// with the application. Rethrowing panic from inside will not be handled by the enclosing recover()
shows() // this way you can call some other function to do some cleanup like closing the connection etc, in case of panic.
}
}() // these closing paranthesis are necessary for the anonymous function
panic("Paniked in panicer().....")
fmt.Println("Done panicking.......")
}
func shows() {
fmt.Println("Statement1......")
a := 10000000000000
defer fmt.Println("In shows() for cleanup......", a) // using defer, that statement will be deferred till the end of the function containing
// this statement, so this will be executed after the last statement of the function is executed, but before execution of panic()
// Check the value of 'a' in both defer statements
fmt.Println("Statement2......")
fmt.Println("Statement3, After this cleanup statement comes......")
a = 0
defer fmt.Println("Last deferred statement....", a) // If there are multiple defer statements then those are executed in LIFO order
}
===============================================================================================
package first
import (
"fmt"
"net/http"
)
// When this function is executed then access - http://localhost:8080/
// to see the below given message printed
// Note it will keep server running on given port 8080, till process is killed manually
// Else if you execute it again without closing previous execution, port will be engaged & you will get the error
// terminating the application, another panic state, as written in if{}
func Web() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello Nitin Agrawal"))
})
err := http.ListenAndServe(":8080", nil)
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
if err != nil {
panic(err.Error()) //panic is used to throw exception when nothing can be done
}
}
===============================================================================================
package main
import (
"first"
"fmt"
"reflect"
)
func main() {
fmt.Println("Second....", first.FirstName)
first.Method1()
first.Another()
first.FileSize()
fmt.Println(first.FileName)
p1 := first.Person{
Name: "Nitin",
Country: "India",
}
printing(p1)
fmt.Println(p1)
job := struct{ jobName string }{jobName: "SE"}
fmt.Println(job)
job.jobName = "Manager"
fmt.Println(job)
fmt.Println(first.Maps("Sangeet", "Today", 40))
first.Logging("https://www.google.com/robots.txt")
first.Web()
}
// Its Pass by Value not Pass by reference
func printing(obj first.Person) {
obj.Country = "Singapore"
t := reflect.TypeOf(first.Person{})
field1, field2 := t.FieldByName("Height") // this way can be used to check if some field or entry is present in Struct or Map
fmt.Printf("Field1 Tag : '%v' Field2 value : %v\n", field1.Tag, field2)
}
===============================================================================================
package main
import (
"fmt"
)
func main() {
var b *mystruct
b = new(mystruct)
b.name = "Nitin"
fmt.Println(b.name)
var result int
s := ranges(&result, 1, 2, 3, 4, 5)
fmt.Println("Sum : ", *s)
fmt.Println("Sum : ", result) // another way to get the result
rs, err := returns(2, 0)
if err != nil {
fmt.Println(err)
// return // this will return the control from the current function if you dont want to execute any further statements in case of issue/error
}
fmt.Println("Result of returns() : ", rs)
var f func(string) = func(name string) {
fmt.Printf("%v called this passed function.", name)
}
functionExecutor(f) // passing the function to other function, this way you can make the lazy execution of some costly function.
}
type mystruct struct {
name string
}
func ranges(rs *int, number ...int) *int { // here we can use (result *int) instead of *int, then we just need to use return only, as the return variable will be taken implicitly as result
result := 0 // here result variable is created on execution stack space of this function which is cleared once execution of the function completes
for index, value := range number {
fmt.Printf("%v, %v \n", index, value)
result += value
}
*rs = result
return &result // as the compiler sees its reference being returned, it promotes this variable to heap space
}
// Returning multiple values or error but this is not the right way to use to return multiple values.
// Error you can return to let the caller handle it rather stopping the application
func returns(a, b float64) (float64, error) { // this way one can return multiple values including the error like shown here
if b == 0 {
return 0.0, fmt.Errorf("Passed value cannot be 0....")
}
return a + b, nil
}
func functionExecutor(f func(name string)) {
f("Nitin")
}
===============================================================================================
import (
"fmt"
// "math"
"strconv"
)
var unused1 string = "unused1"
// unused2 := "unused2"
var FirstName string = "Nitin"
func Method1() {
lastName := "Agrawala"
n := 2
var k uint64 = 78
// var unused3 string = "unused3"
// unused4 := "unused4"
// l := 79
fmt.Printf("%T", k)
// fmt.Println(l-k)
// fmt.Println(unused2)
fmt.Println(string(n))
fmt.Println(strconv.Itoa(n))
fmt.Printf("Hello %v %v %T\n", FirstName, lastName, FirstName)
fmt.Println(10 &^ 3)
var fl float32 = 3.14
fl = 1.2e8
fmt.Printf("%v %T\n", fl, fl)
str := "Nitin Agrawal"
b := []byte(str)
b[3] = 111
fmt.Println(string(b))
fmt.Println(str)
FileSize()
}
func Another() {
fmt.Println("In another()......")
fmt.Println(FirstName)
const a = 4 // make var to const & it will work as during compilation 'a' with its value in the expression to do implicit type conversion
var b int32 = 5
fmt.Println(a + b)
const (
y = iota // it will have 0 as value as it is first element in the tuple
x = true
h // though h is not given any value but still it will get the value as given to its previous
// variable i.e. true here.
z = iota // it will have 3 as value as it is fourth element in the tuple
s = "default"
e // similar to h above it will get the same as given to s above
_ = iota + 2 // _ is used here just to dump the current iota value, so that l below can get next value
l
)
fmt.Printf("%v %v %v\n", x, y, z)
fmt.Printf("%v %v\n", h, e)
fmt.Println(l)
const f = iota
const g = iota
fmt.Printf("%v %v\n", f, g) // here both get 0 as value as both are independent
}
func FileSize() {
const (
B = 1
KB = B * 1024
MB = KB * 1024
GB = MB * 1024
TB = GB * 1024
)
// filesSize := 400000000
fmt.Printf("File Size in GBs : %.2f\n", 400000000.0/GB)
// fmt.Printf("%.2f\n", 12.0/11)
s := [3]int{1, 2, 3}
t := s // Here a complete new copy of 's' is created
t[1] = 4 // it will change the data of t only & not of s
fmt.Println("Original : ", s)
fmt.Println("Copy : ", t)
u := []int{1, 2, 3, 4, 5, 6, 7, 8} //this is how you define a slice, you can use [...] also instead of [], so u is a projection of the array here.
v := u[3:6] // here v is another projection on the array being pointed by u
v[1] = 10
fmt.Println("Original : ", u)
fmt.Println("Copy : ", v)
fmt.Println(len("Nitin"))
fmt.Println(len(u))
}
===============================================================================================
package first
import (
"fmt"
)
func Maps(name, when string, value int) string { // you can can combine similar type of parameters together & say their type only once like shown here
// As shown, one can mention the return type to return
names := map[string]int{
"Ajay": 30,
"Sumit": 28,
"Yasir": 35,
"Sudhir": 27,
name: value,
}
for name, age := range names {
fmt.Printf("%v : %v\n", name, age)
}
return "Done wth map........." // returning the string type of data as mentioned in function signature above
}
===============================================================================================
package first
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func Logging(site string) {
a := "start"
defer fmt.Println("Value of a : ", a) // Check the value of a printed, though it is deferred but its value is processed already which will be used later
// panic("Panic happened............") // If you uncomment this statement then whole application will terminate when this statement is executed
// Also note that, before panic is executed defered statements will be executed first.
// here defer
a = "end"
panicer() // Notice, panic terminates the function it is called from, thats why panic() is called from other function keeping this function
// in running state
fmt.Println("Return from panicer()....")
res, err := http.Get(site)
if err != nil {
fmt.Println(err)
log.Fatal(err)
}
defer res.Body.Close() // If you remove defer then you will get the error as response is closed before it is read in next line
// You can use this way to close this response or connection as soon you open it, not to forget later to close it but defer it.
// But be careful while you are opening the connections in some & you need those connections for that loop only, then use defer
// else you will be make lot of connections open which later can cause the issue.
robots, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
log.Fatal(err)
}
fmt.Printf("Content : %s\n", string(robots[50])) // if you dont use %s then you will get the list of Ascii codes only
}
func panicer() {
fmt.Println("In panicer()......")
defer func() { // this anonymous function & is executed immediately
if err := recover(); err != nil { // using recover(), one can recover from the first panic generated from outside & recover() works only when used from defer func(), as after panic()
// runtime will not execute any more statements but execute the defer statements.
log.Println(err)
// panic(err) //uncomment this then it will terminate the main() method, as we rethrowing the error if it can't be handled to continue
// with the application. Rethrowing panic from inside will not be handled by the enclosing recover()
shows() // this way you can call some other function to do some cleanup like closing the connection etc, in case of panic.
}
}() // these closing paranthesis are necessary for the anonymous function
panic("Paniked in panicer().....")
fmt.Println("Done panicking.......")
}
func shows() {
fmt.Println("Statement1......")
a := 10000000000000
defer fmt.Println("In shows() for cleanup......", a) // using defer, that statement will be deferred till the end of the function containing
// this statement, so this will be executed after the last statement of the function is executed, but before execution of panic()
// Check the value of 'a' in both defer statements
fmt.Println("Statement2......")
fmt.Println("Statement3, After this cleanup statement comes......")
a = 0
defer fmt.Println("Last deferred statement....", a) // If there are multiple defer statements then those are executed in LIFO order
}
===============================================================================================
package first
import (
"fmt"
"net/http"
)
// When this function is executed then access - http://localhost:8080/
// to see the below given message printed
// Note it will keep server running on given port 8080, till process is killed manually
// Else if you execute it again without closing previous execution, port will be engaged & you will get the error
// terminating the application, another panic state, as written in if{}
func Web() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello Nitin Agrawal"))
})
err := http.ListenAndServe(":8080", nil)
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
if err != nil {
panic(err.Error()) //panic is used to throw exception when nothing can be done
}
}
===============================================================================================
package main
import (
"first"
"fmt"
"reflect"
)
func main() {
fmt.Println("Second....", first.FirstName)
first.Method1()
first.Another()
first.FileSize()
fmt.Println(first.FileName)
p1 := first.Person{
Name: "Nitin",
Country: "India",
}
printing(p1)
fmt.Println(p1)
job := struct{ jobName string }{jobName: "SE"}
fmt.Println(job)
job.jobName = "Manager"
fmt.Println(job)
fmt.Println(first.Maps("Sangeet", "Today", 40))
first.Logging("https://www.google.com/robots.txt")
first.Web()
}
// Its Pass by Value not Pass by reference
func printing(obj first.Person) {
obj.Country = "Singapore"
t := reflect.TypeOf(first.Person{})
field1, field2 := t.FieldByName("Height") // this way can be used to check if some field or entry is present in Struct or Map
fmt.Printf("Field1 Tag : '%v' Field2 value : %v\n", field1.Tag, field2)
}
===============================================================================================
package main
import (
"fmt"
)
func main() {
var b *mystruct
b = new(mystruct)
b.name = "Nitin"
fmt.Println(b.name)
var result int
s := ranges(&result, 1, 2, 3, 4, 5)
fmt.Println("Sum : ", *s)
fmt.Println("Sum : ", result) // another way to get the result
rs, err := returns(2, 0)
if err != nil {
fmt.Println(err)
// return // this will return the control from the current function if you dont want to execute any further statements in case of issue/error
}
fmt.Println("Result of returns() : ", rs)
var f func(string) = func(name string) {
fmt.Printf("%v called this passed function.", name)
}
functionExecutor(f) // passing the function to other function, this way you can make the lazy execution of some costly function.
}
type mystruct struct {
name string
}
func ranges(rs *int, number ...int) *int { // here we can use (result *int) instead of *int, then we just need to use return only, as the return variable will be taken implicitly as result
result := 0 // here result variable is created on execution stack space of this function which is cleared once execution of the function completes
for index, value := range number {
fmt.Printf("%v, %v \n", index, value)
result += value
}
*rs = result
return &result // as the compiler sees its reference being returned, it promotes this variable to heap space
}
// Returning multiple values or error but this is not the right way to use to return multiple values.
// Error you can return to let the caller handle it rather stopping the application
func returns(a, b float64) (float64, error) { // this way one can return multiple values including the error like shown here
if b == 0 {
return 0.0, fmt.Errorf("Passed value cannot be 0....")
}
return a + b, nil
}
func functionExecutor(f func(name string)) {
f("Nitin")
}
===============================================================================================