├── Concurrency ├── main.go └── note.md ├── Parallelism └── main.go ├── README.md ├── array ├── main.go └── note.txt ├── commant-line-args └── main.go ├── constant ├── iota │ └── main.go └── main.go ├── datatype └── main.go ├── define-type ├── main.go └── note.txt ├── flow-control ├── main.go └── note.txt ├── go.mod ├── interv ├── array vs slice.md ├── go mod go sum.md ├── init.md ├── main.go ├── note.txt └── struct.md ├── loop ├── main.go └── note.txt ├── memory ├── main.go └── note.txt ├── new-feature-1.23-go └── note.txt ├── note.txt ├── operators ├── main.go └── note.txt ├── other └── main.go ├── overflows ├── main.go └── note.txt ├── packagefmt └── main.go ├── pointer └── pointernote.txt ├── scope ├── main.go └── note.txt ├── slice ├── aslice backing array │ ├── main.go │ └── note.txt ├── main.go └── note.txt ├── struct ├── main.go └── note.txt └── variable └── main.go /Concurrency/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func printNumbers() { 9 | for i := 1; i <= 5; i++ { 10 | fmt.Printf("Number: %d\n", i) 11 | time.Sleep(1 * time.Second) // Simulate a delay 12 | } 13 | } 14 | 15 | func printLetters() { 16 | for i := 'A'; i <= 'E'; i++ { 17 | fmt.Printf("Letter: %c\n", i) 18 | time.Sleep(1 * time.Second) // Simulate a delay 19 | } 20 | } 21 | 22 | func main() { 23 | go printNumbers() // run as a goroutine (concurrent) 24 | go printLetters() // run as a goroutine (concurrent) 25 | 26 | time.Sleep(6 * time.Second) // Wait for goroutines to finish 27 | } 28 | -------------------------------------------------------------------------------- /Concurrency/note.md: -------------------------------------------------------------------------------- 1 | **Concurrency and parallelism are two distinct concepts in Go:** 2 | 3 | **Concurrency** is about dealing with lots of things at once—structuring programs where multiple processes run independently, even if they are not actually running simultaneously. 4 | 5 | 6 | **Parallelism** is about doing lots of things simultaneously, and it requires multiple CPU cores. 7 | 8 | 9 | 10 | **Concurrency in Go** 11 | In Go, concurrency is achieved using goroutines and channels. A goroutine is a lightweight thread managed by the Go runtime. -------------------------------------------------------------------------------- /Parallelism/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "sync" 7 | ) 8 | 9 | func printNumbers(wg *sync.WaitGroup) { 10 | defer wg.Done() 11 | for i := 1; i <= 5; i++ { 12 | fmt.Printf("Number: %d\n", i) 13 | } 14 | } 15 | 16 | func printLetters(wg *sync.WaitGroup) { 17 | defer wg.Done() 18 | for i := 'A'; i <= 'E'; i++ { 19 | fmt.Printf("Letter: %c\n", i) 20 | } 21 | } 22 | 23 | func main() { 24 | runtime.GOMAXPROCS(2) // Use 2 CPU cores 25 | 26 | var wg sync.WaitGroup 27 | wg.Add(2) 28 | 29 | go printNumbers(&wg) // run on one CPU core 30 | go printLetters(&wg) // run on another CPU core 31 | 32 | wg.Wait() // Wait for both goroutines to finish 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-programming-2024 2 | go-programming-2024 3 | 4 | 5 |

STAR

6 |

Hi 👋, I'm Manish Kumar

7 |

A passionate Software developer from India

8 | 9 | coding gif 10 | 11 | 12 |

manishkr108

13 | 14 | 15 | 16 | 17 |

manishkr108

18 | 19 | - 🔭 I’m currently working on **Go Lang, JavaScript, Reactjs, PHP, LARAVEL, REST API, MySQL**. 20 | 21 | - 👨‍💻 All of my projects are available at [https://github.com/manishkr108]) 22 | 23 | - 💬 Ask me about **Frontend Development, DSA**. 24 | 25 | - 📫 How to reach me **manishrajpn10@gmail.com** 26 | 27 | 28 | 29 |

Connect with me:

30 |

31 | manishkr108 32 |

33 | 34 | 35 |

Languages and Tools:

36 |

bootstrap css3 docker firebase go html5 java javascript kubernetes laravel mariadb mongodb mssql mysql nginx nodejs oracle php postgresql react redis redux sass tailwind webpack

37 | 38 | 39 | 40 | 42 | 45 | 46 | 47 |

manishkr108

48 | 49 |

 manishkr108

50 | 51 | 52 |

53 | 54 | ### 🔝 Top Contributed Repo 55 | 56 | ![](https://github-contributor-stats.vercel.app/api?username=manishkr108&limit=5&theme=dark&combine_all_yearly_contributions=true) 57 | 58 | 59 | -------------------------------------------------------------------------------- /array/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "strings" 7 | ) 8 | 9 | func main() { 10 | var numbers [5]int 11 | fmt.Printf("%v\n", numbers) //[0 0 0 0 0] 12 | fmt.Printf("%#v\n", numbers) //[5]int{0, 0, 0, 0, 0} 13 | 14 | // other way declear array 15 | 16 | var a1 = [4]float64{} 17 | fmt.Printf("%v\n", a1) //[0 0 0 0] 18 | 19 | var a2 = [3]int{-10, 1, 100} 20 | fmt.Printf("%v\n", a2) //[-10 1 100] 21 | 22 | //short declaration 23 | a3 := [4]string{"manish", "kumar", "raj", "go lang"} 24 | fmt.Printf("%#v\n", a3) //[4]string{"manish", "kumar", "raj", "go lang"} 25 | 26 | a4 := [5]string{"x", "y"} 27 | fmt.Printf("%#v\n", a4) //[5]string{"x", "y", "", "", ""} 28 | 29 | // a nice feature of go is the ellipsis operator or triple dots. it finds out automatically the length of array 30 | a5 := [...]int{1, 2, 3, 4, 5, 5, 6, 7, 8, 89, 7} 31 | fmt.Printf("%#v\n", a5) //[11]int{1, 2, 3, 4, 5, 5, 6, 7, 8, 89, 7} 32 | fmt.Printf("the length of a5 is %d\n", len(a5)) //the length of a5 is 11 33 | fmt.Printf("%T\n", a5) 34 | 35 | // Use reflect to get the type 36 | t := reflect.TypeOf(a5) 37 | 38 | // Check if it's an array or slice 39 | if t.Kind() == reflect.Array { 40 | fmt.Println("This is an array") 41 | } else if t.Kind() == reflect.Slice { 42 | fmt.Println("This is a slice") 43 | } 44 | 45 | /* 46 | In Go, Kind() is a method provided by the reflect package that returns the specific kind of a value. 47 | It helps you determine the underlying data type of an object, whether it's a struct, array, slice, map, pointer, etc. 48 | */ 49 | 50 | abc := [...]int{2, 3, 4, 5, 6, 7, 0} 51 | fmt.Printf("%#v\n", abc) //[7]int{2, 3, 4, 5, 6, 7, 0} 52 | fmt.Printf("%v\n", abc) // [2 3 4 5 6 7 0] 53 | 54 | a6 := [...]int{1, 55 | 2, 56 | 3, 57 | 4, 58 | 5, // in last element must add comma 59 | } 60 | fmt.Println(a6) 61 | 62 | // Add and remove elements 63 | 64 | a6[0] = 9 65 | fmt.Println(a6) //[9 2 3 4 5] 66 | 67 | // a6[10] =12 // invalid argument: index 10 out of bounds -> there is no element index 10 68 | 69 | //How to Iterate array (how many way) 70 | // 1. using range 71 | //range = here range is just a language key word used for iteration. 72 | for i, v := range a6 { 73 | fmt.Println("Index: ", i, "Value:", v) 74 | } 75 | 76 | fmt.Println(strings.Repeat("#", 20)) 77 | //2nd way 78 | 79 | for i := 0; i < len(a6); i++ { 80 | fmt.Println("Index: ", i, "Value:", a6[i]) 81 | } 82 | 83 | // Lets create multi dimention array 84 | 85 | balance := [2][3]int{ 86 | {1000, 2000, 3000}, 87 | {4000, 5000, 6000}, 88 | } 89 | 90 | fmt.Println(balance) 91 | 92 | m := [3]int{1, 2, 3} 93 | 94 | n := m 95 | 96 | fmt.Println("n equal to m :", n == m) //n equal to m : true 97 | m[0] = -1 98 | 99 | fmt.Println("n m :", n, m) //n m : [1 2 3] [-1 2 3] 100 | 101 | fmt.Println("n equal to m :", n == m) //n equal to m : false 102 | // 2 arrays are equal if they have the same length and the same elements, in the same order 103 | 104 | // Array with keyed Elements 105 | 106 | grade := [3]int{ 107 | 1: 90, 108 | 0: 70, 109 | 2: 80, 110 | } 111 | 112 | fmt.Println(grade) // [70 90 80] 113 | 114 | acco := [3]int{2: 50} 115 | fmt.Println(acco) //[0 0 50] 116 | 117 | names := [...]string{ 118 | 5: "paris", 119 | } 120 | fmt.Println(names, len(names)) //[ paris] 6 121 | 122 | city := [...]string{ 123 | 5: "delhi", 124 | "Noida", // index 6 insert in last if key not there 125 | 1: "India", 126 | } 127 | 128 | fmt.Printf("%#v\n", city) //[7]string{"", "India", "", "", "", "delhi", "Noida"} 129 | 130 | weekend := [7]bool{5: true, 6: true} 131 | fmt.Println(weekend) // [false false false false false true true] 132 | } 133 | -------------------------------------------------------------------------------- /array/note.txt: -------------------------------------------------------------------------------- 1 | ----------Array in Go -------------- 2 | 3 | 1. An array is a composit, indexable type that stores a collection of elements of same type. 4 | 2. An array has "fixed length" 5 | 3. Every element in an array must be of same type 6 | 4. Go store the elements of the array in contiguous memory locations and this way its very efficient. 7 | 5. The length and the elements type determines the type of an array. "the length belongs to array type" and its determined at compile time 8 | 9 | example 10 | accounts := [3]int{50,60,70} 11 | 12 | the array called accounts that consists of 3 integers has it type [3]int. 13 | 14 | func main() { 15 | var numbers [5]int 16 | fmt.Printf("%v\n", numbers)//[0 0 0 0 0] 17 | fmt.Printf("%#v\n", numbers)//[5]int{0, 0, 0, 0, 0} 18 | } 19 | 20 | => range = here range is just a language key word used for iteration. 21 | 22 | 23 | // 2 arrays are equal if they have the same length and the same elements, in the same order 24 | 25 | [1,2,3] == [1,2,3] = true 26 | [1,2,3]==[1,3,2] = false 27 | 28 | -------------------------------------------------------------------------------- /commant-line-args/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | /* 10 | ! how to get user input from command line 11 | ! go provide a package like os 12 | ! os.Stdin is the standard input stream 13 | 14 | */ 15 | 16 | func main() { 17 | 18 | // fmt.Println("os.Args", os.Args) 19 | // fmt.Println("Path : ", os.Args[0]) 20 | // fmt.Println("First Arg : ", os.Args[1]) 21 | // fmt.Println("Second Arg : ", os.Args[2]) 22 | // fmt.Println("Length of Args : ", len(os.Args)) 23 | 24 | var result, err = strconv.ParseFloat(os.Args[1], 64) 25 | 26 | fmt.Printf("%T\n", os.Args[1]) 27 | fmt.Printf("%T\n", result) 28 | _ = err 29 | //! SIMPLE STATEMENT 30 | 31 | i, err := strconv.Atoi("45") 32 | 33 | if err != nil { 34 | fmt.Println(err) 35 | } 36 | 37 | fmt.Println(i) 38 | 39 | if i, err := strconv.Atoi("20"); err == nil { 40 | fmt.Println("no error, i is", i) 41 | } else { 42 | fmt.Println(err) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /constant/iota/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | ! IOTA 9 | * within a constant decleration, the predecleared identifier iota represents successive untyped integer constants. 10 | 11 | */ 12 | 13 | func main() { 14 | const ( 15 | c1 = iota 16 | c2 = iota 17 | c3 = iota 18 | ) 19 | 20 | fmt.Println(c1, c2, c3) // 0 1 2 21 | 22 | const ( 23 | North = iota 24 | South 25 | East 26 | West 27 | ) 28 | 29 | fmt.Println(North, South, East, West) //0 1 2 3 30 | 31 | const ( 32 | a = (iota * 2) + 1 33 | b 34 | c 35 | ) 36 | 37 | fmt.Println(a, b, c) //1 3 5 38 | 39 | const ( 40 | i = iota + 5 41 | j 42 | k 43 | ) 44 | 45 | fmt.Println(i, j, k) //5 6 7 46 | 47 | } 48 | -------------------------------------------------------------------------------- /constant/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | ! CONSTANT GO 7 | * In Golang : we use the term constant fixed (unchanging) value. 8 | * We use the keyword const to declare a constant. 9 | * A constant belongs to the compile time and its created at compile time. 10 | * We can't change the value of a constant at runtime. 11 | 12 | */ 13 | 14 | func main() { 15 | // !declare a constant 16 | const PI float64 = 3.14 // * if you declear constant in not use code not throw any error 17 | 18 | var i int 19 | fmt.Println(i) // 0 20 | 21 | x, y := 5, 1 // if i replace 1 to 0 22 | 23 | fmt.Println(x / y) // vs code don't detect error because it run time error 24 | 25 | // const a = 5 26 | // const b = 0 27 | // fmt.Println(a / b) // *panic: runtime error: integer divide by zero 28 | 29 | const n, m = 10, 15 30 | // !define multipal constant 31 | 32 | const ( 33 | r = 10 34 | t 35 | c 36 | ) //! 10 10 10 if i assign one value othe constant is copy to parent value 37 | 38 | fmt.Println(r, t, c) 39 | // todo : CONSTANT RULE 40 | //* 1. constant must be initialized 41 | //* 2. constant must be immutable 42 | const temp int = 30 43 | // * you can not initilizied a constant at run time 44 | // temp = 40 45 | // s := 5 46 | // const tt = s // this is error 47 | 48 | // const x int = 5 49 | // const y float64 = 4.5 * x // this is error 50 | 51 | const xx = 5 52 | const yy = 4.5 * 5 // this is correct 53 | 54 | fmt.Printf("%T\n", yy) 55 | 56 | const rr = 5 57 | var rt = rr 58 | fmt.Printf("%T\n", rt) 59 | 60 | } 61 | -------------------------------------------------------------------------------- /datatype/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | ! ------------------Go Data Types-1------------ 7 | * A type determine a set of value together with operation and methods specific to those value 8 | * There are //! predeclear type, introduced type with type declarations and composite types 9 | * Types: array, slice, map, struct , pointer, function , interface and channel types 10 | 11 | !------Predeclared, Build-in Type--------------- 12 | * Numeric Type 13 | ? + int8, int16, int32, int64, uint8, uint16, 14 | ? uint32, uint64, uintptr, int, uint, float32, float64, complex64 15 | ? complex128, byte, rune, string, bool, error 16 | 17 | */ 18 | func main() { 19 | var i1 int8 = 100 // ! the minimum value of int8 is -128 20 | fmt.Printf("%T\n", i1) 21 | 22 | var i2 uint16 = 65535 23 | fmt.Printf("%T\n", i2) //uint16 24 | 25 | //* Float Type 26 | var f1, f2, f3 float64 = 1.1, -0.2, 5. 27 | fmt.Printf("%T %T %T\n", f1, f2, f3) //float64 float64 float64 28 | 29 | //* Golang does't have char data type , it uses byte and rune represent char values 30 | //!RUNE Type 31 | 32 | var r rune = 'f' 33 | fmt.Printf("%T\n", r) //int32 34 | fmt.Println(r) //102 35 | fmt.Printf("%x\n", r) //66 36 | 37 | //! String Type 38 | var s string = "Hello, Go" 39 | fmt.Printf("%T\n", s) //string 40 | 41 | //* Array Type 42 | var arr [5]int = [5]int{1, 2, 3, 4} 43 | fmt.Printf("%T\n", arr) 44 | 45 | // ! Slice Tyep 46 | var city = []string{"london", "Tokyo", "New York", "4"} 47 | fmt.Printf("%T\n", city) //[]string 48 | 49 | // * Map Tyep 50 | frout := map[string]float64{ 51 | "apple": 1.2, 52 | "banana": 2.3, 53 | "orange": 3.4, 54 | } 55 | fmt.Printf("%T\n", frout) //map[string]float64 56 | 57 | // ! Struct Type 58 | type person struct { 59 | name string 60 | age int 61 | } 62 | var you person 63 | fmt.Printf("%T\n", you) //main.person 64 | 65 | // ! Pointer Type 66 | var xx int = 2 67 | ptr := &xx 68 | fmt.Printf("ptr is of type %T with the value of %v\n", ptr, ptr) //*int 69 | 70 | var golang string = "😊😊" 71 | fmt.Printf("%v\n", golang) //string 72 | 73 | } 74 | -------------------------------------------------------------------------------- /define-type/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | * ------------Define Type ------------ 7 | ? a defined type also called a named type is a new type created by the programmer from another existing type which is called the underlying 8 | ? or source type 9 | ? a defined type is a new name given to an existing type 10 | 11 | 12 | */ 13 | 14 | func main() { 15 | // type age int // * int is its undelying type 16 | // type oldAge age // * int is its underlying type 17 | // type varyoldAge age //* int is its underlying type 18 | 19 | type speed uint 20 | 21 | var s1 speed = 10 22 | var s2 speed = 20 23 | 24 | fmt.Println(s2 - s1) 25 | 26 | var x uint 27 | // x = s1 // * error: deffrent type 28 | x = uint(s1) 29 | _ = x 30 | var s3 speed = speed(x) 31 | fmt.Println(s3) 32 | 33 | //! ---------Alias Declaration---------------- 34 | 35 | var a uint8 = 10 36 | var b byte 37 | b = a 38 | _ = b 39 | 40 | type second = uint 41 | var hour second = 3600 42 | fmt.Printf("minutes in an hour : %d\n", hour/60) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /define-type/note.txt: -------------------------------------------------------------------------------- 1 | % ---------Why define new type------------- 2 | - we can attach methods to newly defined types 3 | - we can define new types that are more specific than the original type 4 | % type safety. we must convert one type into another to perform operations with them. 5 | ? Redability: when we defined a new type lets say type usd float64 we know that new type represents the US Dollar not only floats -------------------------------------------------------------------------------- /flow-control/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | ! flow control if , else if, else statement 7 | * if, else if, and else statement that are used for decision making 8 | 9 | 10 | 11 | */ 12 | 13 | func main() { 14 | 15 | // if statement 16 | price, inStock := 100, true 17 | if price > 80 { 18 | fmt.Println("Price is greater than 80") 19 | } 20 | _ = inStock 21 | 22 | if price <= 100 && inStock { 23 | fmt.Println("buy it!") 24 | } 25 | // this is error in golang 26 | // if price{ 27 | // fmt.Println("price is true") 28 | // } 29 | 30 | if price <= 100 { 31 | fmt.Println("price is less than or equal to 100") 32 | } else if price == 80 { 33 | fmt.Println("On the edge") 34 | } else { 35 | fmt.Println("price is greater than 100") 36 | } 37 | 38 | age := 50 39 | 40 | if age >= 0 && age < 18 { 41 | fmt.Printf("you can not vote! please return in %d years !\n", 18-age) 42 | } else if age == 18 { 43 | fmt.Println("you can vote , this is your first vote") 44 | } else if age > 18 && age <= 100 { 45 | fmt.Printf("you can vote , its important\n") 46 | } else { 47 | fmt.Println("invalid age") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /flow-control/note.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manishkr108/go-programming-2024/b3eb79e7c1980ee25bb8051769648c7b5158f3c8/flow-control/note.txt -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module example.com/go-programming 2 | 3 | go 1.23.1 4 | -------------------------------------------------------------------------------- /interv/array vs slice.md: -------------------------------------------------------------------------------- 1 |

Golang Array vs Slice

2 | 3 |

1. Array in Go

4 | Fixed Size: Arrays in Go have a fixed size defined at the time of declaration, and this size cannot change.
5 | Value Type: Arrays are value types, meaning that when you pass an array to a function, it gets copied.
6 | Memory: Arrays allocate memory for all elements at once, even if they are not used.
7 | 8 | 9 | ----------Array in Go -------------- 10 | 11 | 1. An array is a composit, indexable type that stores a collection of elements of same type. 12 | 2. An array has "fixed length" 13 | 3. Every element in an array must be of same type 14 | 4. Go store the elements of the array in contiguous memory locations and this way its very efficient. 15 | 5. The length and the elements type determines the type of an array. "the length belongs to array type" and its determined at compile time 16 | 17 | example 18 | accounts := [3]int{50,60,70} 19 | 20 | the array called accounts that consists of 3 integers has it type [3]int. 21 | 22 | func main() { 23 | var numbers [5]int 24 | fmt.Printf("%v\n", numbers)//[0 0 0 0 0] 25 | fmt.Printf("%#v\n", numbers)//[5]int{0, 0, 0, 0, 0} 26 | } 27 | 28 | => range = here range is just a language key word used for iteration. 29 | 30 | 31 | // 2 arrays are equal if they have the same length and the same elements, in the same order 32 | 33 | [1,2,3] == [1,2,3] = true 34 | [1,2,3]==[1,3,2] = false 35 | 36 |
37 | Slice 38 | - Has a dynamic length (it can shink or grow) 39 | - The length of a slice is not part of its type, it is determined at runtime 40 | - an uninitialized slice is equal to nil (its zero value is nil) 41 | --------------------------------------------------------------
42 |
  • both slice and an array can contain only same type of elements
  • 43 |
  • we can create a keyed slice like keyed array
  • 44 | 45 | In Go, list := []int{1, 2, 3, 4} is a slice, not an array. 46 | 47 | Here's the difference between a slice and an array in Go: 48 | 49 | Array: An array has a fixed size, which is part of its type, and it cannot be resized. For example:
    50 | 51 | 52 | var arr [4]int = [4]int{1, 2, 3, 4} // This is an array with a fixed length of 4
    53 | Slice: A slice is a dynamically sized, flexible view into the elements of an array. It does not include the size in its type, and you can append or modify it as needed. For example:
    54 | 55 | 56 | list := []int{1, 2, 3, 4} // This is a slice 57 | Since your declaration omits the length ([]int{}), list is a slice. 58 | 59 | In the declaration list := [...]int{2, 3, 4, 5}, this is an array, not a slice. 60 | 61 | The [...] syntax in Go is used to define an array where the length is inferred from the number of elements provided in the literal. In this case, the array has a fixed size of 4 elements. 62 | 63 | Explanation: 64 | Array: The type [...]int{2, 3, 4, 5} means the array has a length of 4, and it's determined by the number of elements between the curly braces. This is a fixed-length array. 65 | 66 | 67 | list := [...]int{2, 3, 4, 5} // Array of length 4 68 | Slice: A slice would not specify the length or use [...]. For example: 69 | 70 | 71 | list := []int{2, 3, 4, 5} // This would be a slice 72 | Since your code uses [...], list is an array. 73 | 74 | 75 | 76 | Here's the comparison between arrays and slices in Go in a table format: 77 | 78 | | **Feature** | **Array** | **Slice** | 79 | |---------------------------|---------------------------------------------------------------------------|----------------------------------------------------------------------| 80 | | **Size** | Fixed size, determined at compile time. | Dynamic size, can grow or shrink. | 81 | | **Syntax** | `var arr [4]int = [4]int{1, 2, 3, 4}` | `var slice []int = []int{1, 2, 3, 4}` | 82 | | **Length** | Length is part of the type (e.g., `[4]int`). | Length is not part of the type (e.g., `[]int`). | 83 | | **Capacity** | Capacity is always equal to length. | Capacity can be larger than the current length. | 84 | | **Memory Allocation** | Allocates memory for all elements, even if unused. | Uses dynamic arrays under the hood, reallocating as needed. | 85 | | **Resizable** | Cannot change size once created. | Can be resized using functions like `append()`. | 86 | | **Reference Behavior** | Direct value type (copy of the array). | Reference type, referencing the underlying array. | 87 | | **Efficiency** | More memory-efficient if the fixed size is known. | More flexible and convenient for variable-sized data. | 88 | | **Passing to Functions** | Passed by value (copy of the array). | Passed by reference (points to the underlying array). | 89 | | **Built-in Functions** | No built-in functions like `append`, `copy`. | Has built-in functions such as `append`, `copy`, `len`, `cap`. | 90 | 91 | 92 | Key Features of Slices: 93 | Dynamic size: The size of a slice can change as elements are added or removed. 94 | 95 | Underlying array: A slice points to a portion of an underlying array. 96 | 97 | Capacity and length: Slices have both length (the number of elements in the slice) and capacity (the total number of elements the underlying array can hold). 98 | 99 | package main 100 | 101 | import "fmt" 102 | 103 | func main() { 104 | // Create a slice with 3 elements 105 | nums := []int{10, 20, 30} // Slice literal (dynamic array) 106 | 107 | fmt.Println("Initial slice:", nums) // Output: [10, 20, 30] 108 | 109 | // Append new elements to the slice 110 | nums = append(nums, 40, 50) 111 | fmt.Println("After appending:", nums) // Output: [10, 20, 30, 40, 50] 112 | 113 | // Slice an existing slice (create a sub-slice) 114 | subSlice := nums[1:4] // Slicing from index 1 to 3 (not including 4) 115 | fmt.Println("Sub-slice:", subSlice) // Output: [20, 30, 40] 116 | 117 | // Modify an element of the sub-slice (this affects the original slice) 118 | subSlice[0] = 25 119 | fmt.Println("Modified sub-slice:", subSlice) // Output: [25, 30, 40] 120 | fmt.Println("Original slice after modification:", nums) // Output: [10, 25, 30, 40, 50] 121 | 122 | // Use the built-in `len` and `cap` functions 123 | fmt.Println("Length of slice:", len(nums)) // Output: 5 124 | fmt.Println("Capacity of slice:", cap(nums)) // Output: 6 (capacity can be larger than the length) 125 | } 126 | 127 | Explanation: 128 | Slice Literal: nums := []int{10, 20, 30} creates a slice with 3 elements. The underlying array is automatically managed by Go.
    129 | Appending: append(nums, 40, 50) adds two new elements to the slice, dynamically increasing its size.
    130 | Slicing: subSlice := nums[1:4] creates a sub-slice from the second to the fourth element of nums. The sub-slice is a reference to the same underlying array, so changes in the sub-slice affect the original slice.
    131 | Modifying a Sub-slice: Changing subSlice[0] updates the original nums slice, showing the reference behavior of slices.
    132 | Length and Capacity: len(nums) gives the current number of elements, and cap(nums) gives the capacity (which can be larger than the length due to underlying array resizing).
    133 | 134 |

    Key Points About Slices:

    135 | Slicing: You can create a new slice from an existing slice using the slicing operator slice[low:high].
    136 | Capacity: Slices may have extra capacity. As you append elements, Go automatically resizes the underlying array when necessary.
    137 | Zero Value: The zero value of a slice is nil, which behaves like a slice with length and capacity 0.
    138 | 139 | 140 |

    Recap of Key Functions:

    141 | append(): Adds elements to a slice, dynamically growing it.
    142 | copy(): Copies elements from one slice to another.
    143 | len(): Returns the current number of elements in the slice.
    144 | cap(): Returns the total capacity of the slice, or how many elements it can hold before resizing.
    145 | 146 | Here’s a simple yet powerful example to supercharge your Go skills with slices👇: 147 | 148 | tasks := []string{"Design", "Develop", "Test"}
    149 | tasks = append(tasks, "Deploy")
    150 | backupTasks := make([]string, len(tasks))
    151 | copy(backupTasks, tasks)
    152 | fmt.Println(tasks, backupTasks)
    153 | 154 | -------------------------------------------------------------------------------- /interv/go mod go sum.md: -------------------------------------------------------------------------------- 1 | In Go, go.mod and go.sum are two important files that help manage dependencies in your Go projects when using Go Modules. Go Modules is the dependency management system introduced in Go 1.11, allowing developers to manage module versions and dependencies more effectively. Here's a brief explanation of each:
    2 | 3 | **1. go.mod** 4 | The go.mod file is the primary configuration file for a Go module. It defines the module's properties, including its name, dependencies, and version information.
    5 | 6 | -------------------------------------------------------------------------------- /interv/init.md: -------------------------------------------------------------------------------- 1 | **Init** 2 | 3 | In Go, the init function is a special function that is executed automatically when a package is initialized, before the main function is called. It is primarily used to set up any necessary initialization logic for the package, such as setting up variables or executing code that should run prior to the program’s main execution.
    4 | 5 | Automatic Execution: The init function is called automatically by the Go runtime; you don't need to call it explicitly.
    6 | 7 | Package Initialization: Each package can have its own init function. If a package imports other packages, the init functions in those imported packages are called before the init function of the importing package.
    8 | 9 | No Arguments and No Return Values: The init function does not take any parameters and does not return any values. You can have multiple init functions within a single package, and they will be executed in the order they appear.
    10 | 11 | Precedes main: The init function is executed before the main function of the program, ensuring that any setup needed for the program's execution is completed first.
    12 | 13 | ***Example of init in Go:*** 14 | 15 | package main 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | // This is the init function for the package 22 | func init() { 23 | fmt.Println("Initializing the package...") 24 | } 25 | 26 | // The main function of the program 27 | func main() { 28 | fmt.Println("Main function called.") 29 | } 30 | 31 | -------------------------------------------------------------------------------- /interv/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // Define the Node struct for a linked list 6 | type Node struct { 7 | data int 8 | next *Node 9 | } 10 | 11 | // Function to print the linked list 12 | func printList(node *Node) { 13 | for node != nil { 14 | fmt.Printf("%d -> ", node.data) 15 | node = node.next 16 | } 17 | fmt.Println("nil") 18 | } 19 | 20 | // Function to merge two sorted linked lists 21 | func mergeLists(l1 *Node, l2 *Node) *Node { 22 | // Create a dummy node to act as the starting point 23 | dummy := &Node{} 24 | current := dummy 25 | 26 | // Traverse both lists and merge them in sorted order 27 | for l1 != nil && l2 != nil { 28 | if l1.data <= l2.data { 29 | current.next = l1 30 | l1 = l1.next 31 | } else { 32 | current.next = l2 33 | l2 = l2.next 34 | } 35 | current = current.next 36 | } 37 | 38 | // If one of the lists has remaining elements, append them 39 | if l1 != nil { 40 | current.next = l1 41 | } else { 42 | current.next = l2 43 | } 44 | 45 | // Return the next node from the dummy node as the merged list's head 46 | return dummy.next 47 | } 48 | 49 | // Function to create a new node 50 | func newNode(data int) *Node { 51 | return &Node{data: data, next: nil} 52 | } 53 | 54 | func main() { 55 | // Create the first sorted linked list: 1 -> 3 -> 5 56 | l1 := newNode(1) 57 | l1.next = newNode(3) 58 | l1.next.next = newNode(5) 59 | 60 | // Create the second sorted linked list: 2 -> 4 -> 6 61 | l2 := newNode(2) 62 | l2.next = newNode(4) 63 | l2.next.next = newNode(6) 64 | 65 | fmt.Println("List 1:") 66 | printList(l1) 67 | 68 | fmt.Println("List 2:") 69 | printList(l2) 70 | 71 | // Merge the two lists 72 | mergedList := mergeLists(l1, l2) 73 | 74 | // Print the merged linked list 75 | fmt.Println("Merged List:") 76 | printList(mergedList) 77 | } 78 | -------------------------------------------------------------------------------- /interv/note.txt: -------------------------------------------------------------------------------- 1 | 1. **what is variadic function** 2 | 3 | In Go, a variadic function is a function that can accept a variable number of arguments. This allows you to pass zero or more arguments of a specified type to the function. Variadic functions are defined using the ... syntax before the type of the variable argument. 4 | 5 | Key Points About Variadic Functions 6 | The variadic parameter must be the last parameter in the function's parameter list. 7 | Inside the function, the variadic parameter is treated as a slice, which means you can iterate over it or access its elements using indexing. 8 | 9 | 10 | package main 11 | 12 | import ( 13 | "fmt" 14 | ) 15 | 16 | // variadic function to calculate the sum of integers 17 | func sum(numbers ...int) int { 18 | total := 0 19 | for _, number := range numbers { 20 | total += number // Add each number to the total 21 | } 22 | return total 23 | } 24 | 25 | func main() { 26 | // Calling the variadic function with different numbers of arguments 27 | fmt.Println("Sum of 1, 2, 3:", sum(1, 2, 3)) // 6 28 | fmt.Println("Sum of 4, 5:", sum(4, 5)) // 9 29 | fmt.Println("Sum of no numbers:", sum()) // 0 30 | fmt.Println("Sum of 10, 20, 30, 40, 50:", sum(10, 20, 30, 40, 50)) // 150 31 | } 32 | 33 | 34 | Advantages of Variadic Functions: 35 | 36 | Flexibility: They allow you to call a function with different numbers of arguments without overloading the function. 37 | Simpler Function Signatures: You can handle various input sizes easily without creating multiple function signatures. 38 | Cleaner Code: Reduces the need for creating different functions for different numbers of parameters. 39 | 40 | What is a Linked List? 41 | 42 | A linked list is a linear data structure where each element is a separate object, called a node. 43 | Each node contains two parts: 44 | Data: The value stored in the node (in this case, an integer). 45 | Next: A pointer or reference to the next node in the sequence. The last node’s next points to nil, which indicates the end of the list.4 46 | 47 | How Linked Lists Work 48 | Singly Linked List: In this type of linked list, each node points only to the next node. 49 | You start with a head pointer, which points to the first node. 50 | You traverse the list from the head, following the next pointers until you reach nil 51 | 52 | 53 | 54 | how many type channel is there please describe 55 | 56 | In Go, channels are a powerful feature used for communication between goroutines. Channels can be thought of as conduits that allow one goroutine to send data to another goroutine in a synchronized manner. Channels in Go come in two main types: 57 | 58 | 1. Unbuffered Channels 59 | 2. Buffered Channels 60 | Let’s break these down in detail: 61 | 62 | 1. Unbuffered Channels: 63 | Definition: In an unbuffered channel, the sender is blocked until a receiver is ready to receive the data, and the receiver is blocked until the sender sends the data. This makes communication synchronous between goroutines. 64 | Use Case: When you want a strict synchronization between the sending and receiving operations. 65 | Behavior: 66 | If a goroutine sends data on an unbuffered channel, it waits until another goroutine is ready to receive that data. 67 | Similarly, if a goroutine tries to receive data, it will wait until another goroutine sends data. 68 | 69 | package main 70 | 71 | import "fmt" 72 | 73 | func main() { 74 | ch := make(chan int) // unbuffered channel 75 | 76 | // Goroutine to send data 77 | go func() { 78 | ch <- 42 // send data 79 | }() 80 | 81 | value := <-ch // receive data 82 | fmt.Println("Received:", value) 83 | } 84 | 85 | 86 | 2. Buffered Channels: 87 | Definition: A buffered channel has a capacity, meaning it can store a limited number of values without blocking the sender. The sender will block only when the buffer is full, and the receiver will block only when the buffer is empty. 88 | Use Case: When you want to decouple the timing of the sending and receiving of data. The sender can send data even if no receiver is ready, as long as the buffer is not full. 89 | Behavior: 90 | If a sender tries to send data and the buffer is not full, it proceeds without blocking. 91 | A receiver can retrieve data from the buffer without waiting if the buffer has data. 92 | The sender blocks if the buffer is full, and the receiver blocks if the buffer is empty. 93 | 94 | package main 95 | 96 | import "fmt" 97 | 98 | func main() { 99 | ch := make(chan int, 2) // buffered channel with a capacity of 2 100 | 101 | // Sending data 102 | ch <- 10 103 | ch <- 20 // buffer is full after this 104 | 105 | fmt.Println(<-ch) // Receive first value (10) 106 | fmt.Println(<-ch) // Receive second value (20) 107 | } 108 | 109 | Directional Channels: 110 | Channels can also be directional, meaning they can be restricted to either sending or receiving. This is more of a design choice to restrict how channels are used within a function. 111 | 112 | 3. Send-Only Channel: 113 | A send-only channel is used to send data but not receive it. 114 | Declaration: chan<- int 115 | 116 | Directional Channels: 117 | Channels can also be directional, meaning they can be restricted to either sending or receiving. This is more of a design choice to restrict how channels are used within a function. 118 | 119 | 3. Send-Only Channel: 120 | A send-only channel is used to send data but not receive it. 121 | Declaration: chan<- int 122 | 123 | 4. Receive-Only Channel: 124 | A receive-only channel is used to receive data but not send it. 125 | Declaration: <-chan int 126 | 127 | func receiveOnly(ch <-chan int) int { 128 | return <-ch 129 | } 130 | 131 | 132 | Practical Example with Both Types of Channels: 133 | 134 | package main 135 | 136 | import ( 137 | "fmt" 138 | "time" 139 | ) 140 | 141 | func sendUnbuffered(ch chan int) { 142 | ch <- 1 // This will block until it's received 143 | } 144 | 145 | func sendBuffered(ch chan int) { 146 | ch <- 2 // This won't block until the buffer is full 147 | } 148 | 149 | func main() { 150 | // Unbuffered channel example 151 | unbufferedCh := make(chan int) 152 | go sendUnbuffered(unbufferedCh) 153 | fmt.Println("Unbuffered Channel received:", <-unbufferedCh) 154 | 155 | // Buffered channel example 156 | bufferedCh := make(chan int, 1) // Buffer size 1 157 | go sendBuffered(bufferedCh) 158 | time.Sleep(time.Second) // Simulating a delay 159 | fmt.Println("Buffered Channel received:", <-bufferedCh) 160 | } 161 | 162 | 163 | what is deffer in go lang explain with example 164 | 165 | n Go, defer is a keyword used to schedule a function to be executed later, typically when the surrounding function returns (either normally or via a panic). This allows you to delay the execution of a function until the current function completes. defer is most commonly used for resource cleanup, like closing files, network connections, or releasing locks, regardless of how the function exits. 166 | 167 | Key Characteristics of defer: 168 | Deferred functions are executed in LIFO (Last In, First Out) order. 169 | Deferred functions run after the surrounding function returns, even if the function exits due to a panic. 170 | Commonly used for resource management (closing files, handling cleanups, etc.). 171 | Example of Using defer: 172 | Let’s look at some practical examples. 173 | 174 | package main 175 | 176 | import "fmt" 177 | 178 | func main() { 179 | fmt.Println("Start") 180 | 181 | defer fmt.Println("This will be printed last") 182 | fmt.Println("Middle") 183 | 184 | fmt.Println("End") 185 | } 186 | 187 | 188 | 2. Using defer to Close a File 189 | A typical use case for defer is when working with resources like files, network connections, or databases. For example, when you open a file, you should ensure it gets closed when you're done using it. With defer, you can ensure the file is closed regardless of how the function exits. 190 | 191 | package main 192 | 193 | import ( 194 | "fmt" 195 | "os" 196 | ) 197 | 198 | func main() { 199 | file, err := os.Open("example.txt") 200 | if err != nil { 201 | fmt.Println("Error opening file:", err) 202 | return 203 | } 204 | // Ensure that the file is closed after the function exits 205 | defer file.Close() 206 | 207 | // Read from the file or perform other operations 208 | fmt.Println("File opened successfully") 209 | } 210 | 211 | 212 | 3. LIFO (Last In, First Out) Execution of Deferred Calls 213 | When multiple defer statements are used, they are executed in reverse order (LIFO). This is useful when dealing with multiple resources that need to be cleaned up in a specific order. 214 | 215 | package main 216 | 217 | import "fmt" 218 | 219 | func main() { 220 | defer fmt.Println("First deferred") 221 | defer fmt.Println("Second deferred") 222 | defer fmt.Println("Third deferred") 223 | fmt.Println("End of main function") 224 | } 225 | 226 | 227 | 4. defer with Function Return Values 228 | defer interacts with function return values in a specific way. If you modify a named return value in the deferred function, it will affect the final return value. 229 | 230 | package main 231 | 232 | import "fmt" 233 | 234 | func example() (result int) { 235 | defer func() { 236 | result++ 237 | }() 238 | return 5 239 | } 240 | 241 | func main() { 242 | fmt.Println(example()) // Output: 6 243 | } 244 | 245 | 246 | 5. defer with Panic and Recover 247 | When a panic occurs, deferred functions are still executed before the program crashes. You can use this to clean up resources or log information just before a crash. 248 | 249 | package main 250 | 251 | import "fmt" 252 | 253 | func main() { 254 | defer fmt.Println("Deferred function - will be executed even after panic") 255 | 256 | fmt.Println("This will run first") 257 | 258 | panic("Something went wrong!") 259 | 260 | fmt.Println("This will not be executed") 261 | } 262 | 263 | 264 | 6. defer in Loops 265 | You need to be careful when using defer inside loops, as it will delay execution of the deferred function until the surrounding function exits, not after each iteration of the loop. 266 | 267 | package main 268 | 269 | import "fmt" 270 | 271 | func main() { 272 | for i := 0; i < 3; i++ { 273 | defer fmt.Println(i) 274 | } 275 | fmt.Println("Deferred prints after this") 276 | } 277 | 278 | 279 | what is error how to handel error in go lang 280 | 281 | 282 | In Go, an error is a built-in interface that represents something going wrong during the execution of a program. Instead of using exceptions like some other languages (e.g., Python, Java), Go uses explicit error handling through return values. This means that errors are returned as part of the function’s result and need to be checked explicitly. 283 | 284 | Error Handling in Go 285 | Errors are returned as values: Functions that can fail usually return an error as an additional return value. 286 | The caller checks the error: After calling a function, it’s the caller's responsibility to check if the error is nil or not. 287 | 288 | type error interface { 289 | Error() string 290 | } 291 | 292 | Panic and Recover 293 | While Go encourages explicit error handling, it also has a way to handle exceptional situations using panic and recover. These should be used sparingly, typically for truly exceptional cases (like program crashes). 294 | 295 | panic(): Stops the normal execution of the program and starts panicking. 296 | recover(): Allows you to regain control of a panicking program. 297 | 298 | package main 299 | 300 | import ( 301 | "fmt" 302 | ) 303 | 304 | func riskyOperation() { 305 | defer func() { 306 | if r := recover(); r != nil { 307 | fmt.Println("Recovered from panic:", r) 308 | } 309 | }() 310 | 311 | panic("Something went terribly wrong") 312 | } 313 | 314 | func main() { 315 | fmt.Println("Starting program...") 316 | riskyOperation() 317 | fmt.Println("Program continues after recovery") 318 | } 319 | 320 | 321 | Best Practices for Error Handling in Go 322 | Return errors as soon as they occur: If a function encounters an error, return it immediately instead of continuing execution. 323 | Use custom error types for more complex error scenarios, especially if additional context is needed (e.g., error codes or messages). 324 | Use errors.Is and errors.As from the errors package to check and unwrap errors. 325 | Avoid using panic unless necessary: panic is meant for truly exceptional cases, not for normal error handling. Use explicit error handling with return values instead. 326 | Log errors: Always log errors with enough information to understand what went wrong. 327 | Defer resource cleanup: Use defer to ensure that resources (files, connections, etc.) are properly closed, even in the case of errors. 328 | 329 | 330 | Example: Checking Error Types with errors.Is 331 | Go’s standard library offers some helper functions for working with errors, like errors.Is and errors.As, which are useful for checking error types. 332 | 333 | 334 | package main 335 | 336 | import ( 337 | "errors" 338 | "fmt" 339 | ) 340 | 341 | var ErrNotFound = errors.New("resource not found") 342 | 343 | func fetchData(id int) error { 344 | if id == 0 { 345 | return ErrNotFound 346 | } 347 | return nil 348 | } 349 | 350 | func main() { 351 | err := fetchData(0) 352 | if errors.Is(err, ErrNotFound) { 353 | fmt.Println("Error: data not found") 354 | } else if err != nil { 355 | fmt.Println("An unknown error occurred") 356 | } else { 357 | fmt.Println("Data fetched successfully") 358 | } 359 | } 360 | 361 | 362 | What is an Anonymous Function in Go? 363 | An anonymous function is a function that is defined without a name. In Go, like many other languages, functions are first-class citizens, meaning they can be assigned to variables, passed as arguments, or returned from other functions. Anonymous functions are often used for quick, one-time operations where defining a named function is unnecessary. 364 | 365 | Syntax of Anonymous Function in Go 366 | Here’s a basic example of an anonymous function:4 367 | 368 | package main 369 | 370 | import "fmt" 371 | 372 | func main() { 373 | // Anonymous function assigned to a variable 374 | greet := func(name string) { 375 | fmt.Println("Hello,", name) 376 | } 377 | 378 | greet("Manish") // Calling the anonymous function 379 | } 380 | Why Use Anonymous Functions? 381 | Short-lived or One-time Use: Anonymous functions are useful when you need to define a function for a short period or use it only once. Instead of defining a separate, named function, you can use an anonymous function for quick operations. 382 | 383 | Functional Programming Techniques: You can pass anonymous functions as arguments to other functions, or return them as results. This enables techniques like callbacks and functional composition. 384 | 385 | Closure Support: Anonymous functions in Go are closures, meaning they can capture and use variables from their surrounding scope. 386 | 387 | Keeping the Code Clean: When a function is used only in a local context and doesn’t need to be reused elsewhere, anonymous functions help reduce clutter by keeping the definition inline. 388 | 389 | 390 | Example 1: Anonymous Function as an Argument 391 | Anonymous functions can be passed directly as arguments to higher-order functions (functions that take other functions as arguments). 392 | 393 | package main 394 | 395 | import "fmt" 396 | 397 | // Higher-order function that takes a function as an argument 398 | func processData(operation func(int, int) int) { 399 | result := operation(10, 20) 400 | fmt.Println("Result:", result) 401 | } 402 | 403 | func main() { 404 | // Passing an anonymous function as an argument 405 | processData(func(a, b int) int { 406 | return a + b 407 | }) 408 | } 409 | 410 | Example 2: Closure with an Anonymous Function 411 | An anonymous function in Go can capture variables from the surrounding context. This behavior is known as a closure. 412 | 413 | package main 414 | 415 | import "fmt" 416 | 417 | func main() { 418 | counter := 0 419 | 420 | // Anonymous function capturing the 'counter' variable 421 | increment := func() { 422 | counter++ 423 | fmt.Println("Counter:", counter) 424 | } 425 | 426 | increment() // Output: Counter: 1 427 | increment() // Output: Counter: 2 428 | } 429 | 430 | 431 | Example 3: Returning an Anonymous Function 432 | Go allows you to return anonymous functions from other functions. This enables functional programming patterns where functions can be generated dynamically. 433 | 434 | package main 435 | 436 | import "fmt" 437 | 438 | // Function that returns an anonymous function 439 | func createAdder(x int) func(int) int { 440 | return func(y int) int { 441 | return x + y 442 | } 443 | } 444 | 445 | func main() { 446 | add10 := createAdder(10) // Creates a function that adds 10 447 | result := add10(5) // Uses the returned function 448 | fmt.Println("Result:", result) 449 | } 450 | 451 | 452 | When Should You Use Anonymous Functions? 453 | Callbacks and Event Handling: If you need to define a function that is only used in one place (like handling a button click, processing data, or handling a callback in an API call), anonymous functions are ideal. 454 | 455 | Functional Programming Patterns: In scenarios where functions are passed as arguments or returned as values, anonymous functions make it easy to define functions inline. 456 | 457 | Closures: If your function needs to capture and use variables from its surrounding scope (like maintaining state across multiple function calls), an anonymous function as a closure is useful. 458 | 459 | Encapsulation: If you want to hide implementation details that aren't needed elsewhere in your program, anonymous functions provide a way to define and use the logic without cluttering your code with named functions. 460 | 461 | Example of Cross-Compiling for Multiple Systems: 462 | If you want to generate build files for Linux, macOS, and Windows, you can run the following 463 | 464 | # Linux 64-bit 465 | GOOS=linux GOARCH=amd64 go build -o build-linux main.go 466 | 467 | # macOS 64-bit 468 | GOOS=darwin GOARCH=amd64 go build -o build-macos main.go 469 | 470 | # Windows 64-bit 471 | GOOS=windows GOARCH=amd64 go build -o build-windows.exe main.go 472 | 473 | 474 | 475 | -------------------------------------------------------------------------------- /interv/struct.md: -------------------------------------------------------------------------------- 1 |

    What is struct

    2 | 3 | -> struct (short for "structure") is a composite data type that groups together different variables under a single name.
    4 | ->Each of these variables can be of different types, and they are called fields of the struct.
    5 | -> In Go, Struct are one of the most powerful and commonly used data type
    6 | -> Struct allow you to group related data together, making your code more orgnized and easy to work with.
    7 | 8 | type Person struct { 9 | Name string 10 | Age int 11 | Address string 12 | } 13 | 14 | main 15 | person1 := Person{ 16 | Name: "John Doe", 17 | Age: 30, 18 | Address: "123 Main Street", 19 | } 20 | 21 | // Accessing the fields 22 | fmt.Println("Name:", person1.Name) 23 | fmt.Println("Age:", person1.Age) 24 | fmt.Println("Address:", person1.Address) 25 | 26 | // Modifying a field 27 | person1.Age = 31 28 | fmt.Println("Updated Age:", person1.Age) 29 | 30 | A struct is a callection of fields, where each field has its own type.
    31 | it's similar to classes in other programming language, but without method attached. 32 | 33 |

    Syntex

    34 | 35 | type Person struct { 36 | Name string 37 | Age int 38 | } 39 | 40 | 41 | type Event struct { 42 | ID int64 // id of the event 43 | Name string `json:"name" binding:"required"` // name of the event 44 | Description string `json:"description" binding:"required"` 45 | Location string `json:"location" binding:"required"` // location of the event 46 | StartTime time.Time `json:"startTime" binding:"required"` // start time of the event 47 | UserID int64 `json:"user_id"` 48 | } 49 | 50 |

    Anonymous Structs

    51 | - Go also allow the use of anonymous structs, which does't require pre-defined type
    52 | - You can define and use a struct without explicitly creating a named type. This is useful for quick one-off uses where you don’t need to reuse the struct elsewhere.
    53 | 54 | **example** 55 | person := struct { 56 | Name string 57 | Age int 58 | }{ 59 | Name: "Alice", 60 | Age: 25, 61 | } 62 | 63 | fmt.Println(person.Name) // Output: Alice 64 | 65 | **3. Embedded Struct (Struct Composition)** 66 | 67 | Go doesn’t support inheritance, but you can achieve a similar effect using struct embedding. This allows one struct to contain another, effectively reusing fields from the embedded struct.
    68 | 69 | **Example** 70 | type Address struct { 71 | City string 72 | State string 73 | } 74 | 75 | type Person struct { 76 | Name string 77 | Age int 78 | Address // Embedded struct 79 | } 80 | 81 | func main() { 82 | person := Person{ 83 | Name: "John", 84 | Age: 30, 85 | Address: Address{ 86 | City: "New York", 87 | State: "NY", 88 | }, 89 | } 90 | 91 | fmt.Println(person.City) // Output: New York 92 | fmt.Println(person.State) // Output: NY 93 | } 94 | 95 | 96 | **4. Struct with Methods** 97 | -Go allows you to associate methods with a struct, enabling you to create behavior associated with the data within the struct.
    98 | 99 | type Person struct { 100 | Name string 101 | Age int 102 | } 103 | 104 | // Method associated with the Person struct 105 | func (p Person) Greet() { 106 | fmt.Printf("Hello, my name is %s.\n", p.Name) 107 | } 108 | 109 | func main() { 110 | person := Person{Name: "Bob", Age: 25} 111 | person.Greet() // Output: Hello, my name is Bob. 112 | } 113 | 114 | **5. Pointer to a Struct** 115 | -Go allows you to use pointers with structs. This is particularly useful for modifying the struct's data or avoiding the cost of copying large structs.
    116 | 117 | type Person struct { 118 | Name string 119 | Age int 120 | } 121 | 122 | func modifyPerson(p *Person) { 123 | p.Age = 30 124 | } 125 | 126 | func main() { 127 | person := Person{Name: "Alice", Age: 25} 128 | modifyPerson(&person) 129 | fmt.Println(person.Age) // Output: 30 130 | } 131 | 132 | **6. Tagged Structs** 133 | You can add tags to struct fields, often used in conjunction with serialization (like json, xml, etc.). These tags help control how data is marshaled or unmarshaled.
    134 | 135 | package main 136 | 137 | import ( 138 | "encoding/json" 139 | "fmt" 140 | ) 141 | 142 | // User struct with a JSON tag for username 143 | type User struct { 144 | Username string `json:"username"` // JSON tag 145 | } 146 | 147 | func main() { 148 | // Create an instance of User 149 | user := User{ 150 | Username: "john_doe", 151 | } 152 | 153 | // Marshal the struct to JSON 154 | jsonData, err := json.Marshal(user) 155 | if err != nil { 156 | fmt.Println("Error marshaling to JSON:", err) 157 | return 158 | } 159 | 160 | // Print the JSON output 161 | fmt.Println(string(jsonData)) // Output: {"username":"john_doe"} 162 | } 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /loop/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | for i := 0; i < 10; i++ { 7 | fmt.Println(i) 8 | 9 | } 10 | 11 | //! Go dont have while loop below code is same effect as while loop 12 | j := 10 13 | for j > 10 { 14 | fmt.Println(j) 15 | j-- 16 | } 17 | // Infinie loop 18 | // sum := 0 19 | 20 | // for { 21 | // sum++ 22 | // } 23 | // fmt.Println(sum) 24 | 25 | // * Continue Statement 26 | 27 | for i := 0; i < 10; i++ { 28 | if i%2 != 0 { 29 | continue 30 | } 31 | fmt.Println(i) 32 | } 33 | 34 | // ! Breck Statement 35 | 36 | count := 0 37 | 38 | for i := 0; true; i++ { 39 | if i%13 == 0 { 40 | fmt.Printf("%d divided by 13\n", i) 41 | count++ 42 | } 43 | if count == 10 { 44 | break // breack statement is not teminate program intirely it is jumping out of the loop and program continue at the statement following curlybreckets 45 | 46 | } 47 | } 48 | 49 | fmt.Println("just a message") 50 | 51 | // !--------LEBEL Statement --------------- 52 | 53 | people := [5]string{"hey", "mani", "kumar", "bangalore", "all good"} 54 | frends := [2]string{"mani", "raj"} 55 | 56 | outer: 57 | for index, name := range people { 58 | for _, frnd := range frends { 59 | if name == frnd { 60 | fmt.Printf("a friend %q at index %d\n", frnd, index) 61 | break outer 62 | } 63 | } 64 | } 65 | fmt.Println(" Next instraction after loop") 66 | 67 | //! GOTO 68 | 69 | ii := 0 70 | loop: 71 | if ii < 5 { 72 | fmt.Println(ii) 73 | ii++ 74 | goto loop 75 | } 76 | 77 | //! Switch Statement 78 | 79 | language := "golang" 80 | switch language { 81 | case "java": 82 | fmt.Println("java is a language") 83 | case "c": 84 | fmt.Println("c is a language") 85 | case "golang": 86 | fmt.Println("golang is a language") 87 | default: 88 | fmt.Println("language not found") 89 | } 90 | 91 | n := 5 92 | switch true { 93 | case n%2 == 0: 94 | fmt.Println("Even Number") 95 | case n%2 != 0: 96 | fmt.Println("Odd Number") 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /loop/note.txt: -------------------------------------------------------------------------------- 1 | % ------------- Labels Statement ------------------ 2 | - labels are used in breck, continue and goto Statement 3 | - it is illegal to define a label that is never used. 4 | - most of the time labels are used to terminate outer enclosing loops 5 | - labels are used to jump to a specific point in the code. 6 | -------------------------------------------------------------------------------- /memory/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | files := make([]*os.File, 0) 10 | for i := 0; ; i++ { 11 | file, err := os.OpenFile("test.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) 12 | if err != nil { 13 | fmt.Printf("Error at file %d: %v\n", i, err) 14 | break 15 | } else { 16 | _, _ = file.Write([]byte("Hello, World!")) 17 | files = append(files, file) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /memory/note.txt: -------------------------------------------------------------------------------- 1 | Memory leaks are a common issue regardless of the programming language used. However, it’s relatively complex to write memory-leaking code in Go. This article will illustrate several scenarios where memory leaks may occur, allowing us to learn how to avoid them by studying these anti-patterns. 2 | 3 | Not Closing Opened Files 4 | When you finish an open file, you should always call its Close method. Failing to do so may result in reaching the maximum number of file descriptors, preventing you from opening new files or connections. This can lead to a "too many open files" error, as shown below: 5 | 6 | 7 | -------------------------------------------------------------------------------- /new-feature-1.23-go/note.txt: -------------------------------------------------------------------------------- 1 | 🌟🚀 Exciting News: Go 1.23 is Here! 🚀🌟 2 | If you’re a #Golang developer, you’re going to LOVE the new features and improvements in the Go 1.23 release! 🎉 This version brings key updates that make coding faster, more secure, and more productive. Whether you’re into backend services, microservices, or just love building in Go, these changes are bound to enhance your workflow! ⚡️ 3 | 4 | Check out some of the most exciting features in Go 1.23: 5 | 6 | 1. Improved Error Handling 🛠️ 7 | Go 1.23 introduces more powerful error wrapping and unwrapping functions. Error handling is now cleaner and more maintainable, thanks to updates in errors package. Debugging and tracing complex error chains just got easier! 🔗 8 | 9 | 2. Optimized Garbage Collector ♻️ 10 | Better performance through adaptive memory management! The garbage collector is now even more efficient, optimizing memory usage for large-scale applications and reducing latency. Your services will run faster and smoother with less memory overhead. 11 | 12 | 3. Type Parameters Enhancements 🔢 13 | Generics got a massive update in Go 1.23! With new features for type parameters, developers can now create more flexible and reusable functions and data structures. This opens up tons of possibilities for reducing code duplication. 14 | 15 | 4. Concurrency Improvements 🕸️ 16 | Go 1.23 makes concurrent programming safer with additional tools to avoid race conditions. New goroutine leak detection features help identify issues during testing, making concurrency bugs easier to squash! 🐛 17 | 18 | 5. TLS 1.3 as Default 🔐 19 | Go 1.23 now defaults to TLS 1.3, making it even more secure for web applications and services. Stronger encryption and faster handshakes mean both security and performance are improved. 20 | 21 | 6. Debugger Enhancements 🐞 22 | With better support for debuggers like Delve, diagnosing issues in Go programs just became more straightforward. New symbols and debug info give you more control while debugging your Go apps. 23 | 24 | 7. Better Cross-Compilation Support 🌐 25 | Go 1.23 includes improved cross-compilation for various platforms. Now, building Go applications for different operating systems and architectures is easier, thanks to additional platform-specific optimizations. 26 | 27 | 🚀 These updates are going to take Go to new heights in 2024 and beyond! Whether you're building fast APIs, scalable microservices, or high-performance systems, Go 1.23 has something for you. Start exploring today, and share your experiences with the community! 💬👇 28 | -------------------------------------------------------------------------------- /note.txt: -------------------------------------------------------------------------------- 1 | % Go is a tool for managing Go source code 2 | 3 | -> 1 - Go run: it compiles and run the application. it does't produce an executable 4 | - go run file.go: compiles and immediately runs Go programs. 5 | -> 2 - go build: it just compiles the application. it produces an executable 6 | ? go build file.go: compiles a bunch of Go source file. it compiles packages and dependencies. 7 | - if you run go build it will compile the file in the current directory and will produce an executable file with the name of 8 | - the working directory. 9 | ! go build -o app will produce an executable file called app 10 | % Compile for Windows -> GOOS=windows GoARCH=amd64 build -0 wiapp.exe 11 | 12 | ? Go strong suggest certain style 13 | - Gofmt which coms from golang formatter will formate a programs cource code in an idiomatic way that is easy to ready and understand. 14 | ! this tool, gofmt is built into the language runtime, and it formates go cide according to a set stable , well understand language rules. 15 | ! gofmt -w file.go will format the file and write the result back to the file. 16 | -------------------------------------------------------------------------------- /operators/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | ! -----------OPERATORS-------- 7 | * An operators is a symbol of the programming language which is able to "operate on value". 8 | * Operators are used to perform operations on variables and values. 9 | ! 1. Arthmetic and BitWise Operators : +,-,*,/,%,&,|,^,<<,>> 10 | ! 2. Assignment Operators : =,+=,-=,*=,/= 11 | ! 3. Compairsion Operators: ==,!=, <,>, >=, 12 | ! 4. Logical Operators : &&,||,! 13 | ! 5. Operators for Pointers (&) and channels (<-) 14 | 15 | */ 16 | 17 | func main() { 18 | // Arithmetic 19 | 20 | a, b := 6, 2 21 | r := (a + b) / (a - b) * 2 22 | fmt.Println(r) // 6 23 | 24 | c, d := 2, 3 25 | c += d 26 | fmt.Println(c) 27 | 28 | x := 3 29 | x += 1 30 | x++ 31 | fmt.Println(x) //5 32 | // fmt.Println(5 + x++) // this is incorrect way in go 33 | fmt.Println(a == b) // false 34 | fmt.Println(a != b) // true 35 | fmt.Println(a, b) 36 | fmt.Println(a > b) // true 37 | fmt.Println(a < b) // false 38 | fmt.Println(a >= b) // true 39 | fmt.Println(a <= b) // false 40 | } 41 | -------------------------------------------------------------------------------- /operators/note.txt: -------------------------------------------------------------------------------- 1 | % Comparison Operators : Compare two operands and yield an boolean value. 2 | - There are the following comparision Operators; 3 | - Equal to (==) 4 | - Not Equal to (!=) 5 | - Greater than (>) 6 | - Less than (<) 7 | - less or equal (<=) 8 | - Greater or equal (>=) 9 | example 10 | a,b := 5,10 11 | fmt.Println(a ==b )// false 12 | fmt.Println(a !=b )// true 13 | fmt.Println(a > b )// false 14 | fmt.Println(a < b )// true 15 | fmt.Println(a >= b )// false 16 | fmt.Println(a <= b )// true 17 | 18 | % -----------Logical Operators----------------- 19 | - Logical operators apply to boolean values and yield a result of the same type as the operands (boolean) 20 | - There are the following logical operators; 21 | && (conditional and) 22 | || (conditional or) 23 | ! (not) 24 | - example 25 | a,b := true,false 26 | fmt.Println(a && b )// false 27 | fmt.Println(a || b )// true 28 | fmt.Println(!a )// false 29 | 30 | -------------------------------------------------------------------------------- /other/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | name, age := "manish", 30 7 | fmt.Printf("%s is %d \n", name, age) 8 | 9 | fmt.Printf("%[2]s is %[1]d\n", age, name) 10 | 11 | fmt.Printf("%[1]T (%[1]v)\n", name) 12 | fmt.Printf("%[1]T (%[1]v)\n", age) 13 | 14 | fmt.Printf("My name is %s. Yes, you heard that right: %s\n", name, name) 15 | 16 | fmt.Printf("My name is %[1]s. Yes, you heard that right: %[1]s\n", name) 17 | 18 | number := 10000000 19 | better := 10_000_000 20 | 21 | fmt.Println(number == better) 22 | } 23 | -------------------------------------------------------------------------------- /overflows/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | var x uint8 = 255 10 | x++ // overflow , xis 0 11 | 12 | fmt.Println(x) 13 | 14 | // a := int8(255 + 1) 15 | // fmt.Println(a)// Constant 256 overflows int8 16 | 17 | var t = 3 // ! type int 18 | var u = 3.5 // * type float64 19 | 20 | y := t * int(u) 21 | 22 | fmt.Println(y) 23 | 24 | fmt.Printf("%T\n", t) 25 | fmt.Printf("%T\n", u) 26 | 27 | // int and int64 not a equal 28 | var a = 5 29 | var b int64 = 5 30 | 31 | // fmt.Println(a == b) //* invalid operation: a == b (mismatched types int and int64)compilerMismatchedTypes) 32 | fmt.Println(a == int(b)) 33 | 34 | s := string(99) 35 | fmt.Println(s) //c 36 | 37 | //s1 := string(66.5) //*cannot convert 66.5 (untyped float constant) to type stringcompilerInvalidConversion 38 | var mystr = fmt.Sprintf("%f\n", 44.2) 39 | fmt.Println("value of mystr is ", mystr) 40 | fmt.Printf("%T\n", mystr) 41 | 42 | var mystr1 = fmt.Sprintf("%d\n", 34234) 43 | fmt.Println("value of mystr1 is ", mystr1) 44 | fmt.Printf("%T\n", mystr1) 45 | fmt.Println(string(35234)) 46 | 47 | s1 := "3.565" 48 | fmt.Printf("%T\n", s1) //string 49 | 50 | var f1, err = strconv.ParseFloat(s1, 64) 51 | 52 | _ = err 53 | fmt.Println(f1) 54 | /* 55 | !func strconv.ParseFloat(s string, bitSize int) (float64, error) 56 | *ParseFloat converts the string s to a floating-point number with the precision specified by bitSize: 32 for float32, or 64 for float64. 57 | * When bitSize=32, the result still has type float64, but it will be convertible to float32 without changing its value 58 | */ 59 | 60 | i, err := strconv.Atoi("-50") //I type is int, i value is -50 61 | s2 := strconv.Itoa(20) //S2 type is string, S2 value is 20 62 | 63 | fmt.Printf("I type is %T, i value is %v\n", i, i) 64 | fmt.Printf("S2 type is %T, S2 value is %v\n", s2, s2) 65 | 66 | // ! math.Pow() to calculate the power 67 | 68 | } 69 | -------------------------------------------------------------------------------- /overflows/note.txt: -------------------------------------------------------------------------------- 1 | var a = 5 2 | var b int64 = 5 3 | 4 | - fmt.Println(a == b) //* invalid operation: a == b (mismatched types int and int64)compilerMismatchedTypes) 5 | 6 | % ------number to string --and -- String to Number 7 | s := string(99) 8 | fmt.Println(s)//c 9 | 10 | - Other conversion 11 | // 1. string to int strconv.Atoi(string to int) 12 | - strconv.Itoa // int to assice 13 | // 2. string to float strconv.ParseFloat(string to float) 14 | 15 | -------------------------------------------------------------------------------- /packagefmt/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | ! fmt package in details 9 | * the varbs inside the template string start with percent sign followed by a single letter 10 | ?Exampe 11 | ! %d is a verb tells Printf that it should replace it with an integer. 12 | * duble cort inside duble cort go is not allow slash then you can use 13 | */ 14 | 15 | func main() { 16 | fmt.Println("Hello, World!") 17 | 18 | fmt.Printf("your %d is your age\n", 21) 19 | 20 | fmt.Printf("X is %d, y is %f", 5, 7.5) 21 | //fmt.Printf("He says: "Hello Go!"")// this is not allow 22 | fmt.Printf("he says: \"hello!\"") // it allow 23 | 24 | figure := "circle" 25 | radius := 5 26 | pi := 3.14159 27 | 28 | _, _ = figure, pi 29 | fmt.Printf("Redius is %+d\n ", radius) 30 | 31 | fmt.Printf("this is PI value %f\n", pi) 32 | 33 | // ! %q for quoted string 34 | fmt.Printf("this is a %q\n", figure) 35 | 36 | // ! %v -> replace by any type 37 | 38 | fmt.Printf("this diameter of a %v with a radius of %v is %v\n", figure, radius, pi) 39 | 40 | // ! %T -> type 41 | fmt.Printf("figure is of type %T\n", figure) // string 42 | fmt.Printf("radius is of type %T\n", radius) // Int 43 | fmt.Printf("Pi is of type %T\n", pi) // float64 44 | 45 | // ! %t -> bool 46 | close := true 47 | fmt.Printf("file close %t\n", close) 48 | 49 | // ! %b = base 2 50 | fmt.Printf("binary of 5 is %08b\n", 55) 51 | fmt.Printf("Decimal of 100 is %x\n", 100) 52 | 53 | x := 5.3 54 | y := 6.7 55 | 56 | fmt.Printf("X * Y = is %.3f\n", x*y) 57 | } 58 | -------------------------------------------------------------------------------- /pointer/pointernote.txt: -------------------------------------------------------------------------------- 1 | In Go, pointers are variables that store the memory address of another variable. They allow you to work with references to values rather than the values themselves, enabling you to modify data at the original memory location, avoid copying large data structures, and improve performance in some cases. 2 | 3 | 4 | What is a Pointer in Go? 5 | A pointer in Go is a variable that holds the address of another variable. In Go, the type of a pointer is written with an asterisk (*) followed by the type of the variable it points to. The pointer stores the memory address where a value is located, not the value itself. 6 | 7 | The address-of operator (&) is used to get the memory address of a variable. 8 | The dereference operator (*) is used to access or modify the value at the memory address the pointer is pointing to. 9 | 10 | 11 | Benefits of Pointers in Go: 12 | 1. Avoid copying large data structures: Pointers let you avoid copying entire structs, arrays, or slices, which is more efficient for large data. 13 | 14 | 2. Modify data: With pointers, you can modify the value at the memory address directly, enabling functions to update the original variables without returning them. 15 | 16 | 3. Pass by reference: By passing pointers to functions, you avoid passing by value (which would create a copy of the data), thus saving memory and improving performance. 17 | 18 | 19 | EXAMPLE 20 | package main 21 | 22 | import "fmt" 23 | 24 | func main() { 25 | var x int = 10 // Declare an integer variable x with value 10 26 | var p *int // Declare a pointer p to an int 27 | 28 | p = &x // Store the address of x in the pointer p 29 | 30 | fmt.Println("x:", x) // Output: x: 10 31 | fmt.Println("p:", p) // Output: p: (memory address of x) 32 | fmt.Println("*p:", *p) // Output: *p: 10 (value at the memory address p is pointing to) 33 | 34 | *p = 20 // Modify the value at the memory address p is pointing to (this changes x) 35 | 36 | fmt.Println("x after *p = 20:", x) // Output: x after *p = 20: 20 37 | } 38 | 39 | 40 | Explanation: 41 | x is a normal integer with value 10. 42 | p is a pointer that holds the memory address of x (p = &x). 43 | *p accesses the value stored at the address p is pointing to (x's value). 44 | Changing *p = 20 modifies the value at the memory address, so x is now 20. 45 | 46 | 47 | 2. Pointers with Functions 48 | Pointers are useful when you want to modify the value of a variable within a function. 49 | 50 | package main 51 | 52 | import "fmt" 53 | 54 | func changeValue(val *int) { 55 | *val = 100 // Modify the value at the memory address pointed to by val 56 | } 57 | 58 | func main() { 59 | x := 50 60 | fmt.Println("Before:", x) // Output: Before: 50 61 | 62 | changeValue(&x) // Pass the address of x to the function 63 | fmt.Println("After:", x) // Output: After: 100 (x has been modified) 64 | } 65 | 66 | Explanation: 67 | The function changeValue takes a pointer to an int (val *int). 68 | Inside the function, *val = 100 changes the value at the memory address val is pointing to. 69 | This modification is reflected in the original variable x because we passed the address of x (&x). 70 | 71 | 3. Pointers and Structs 72 | 73 | Pointers are especially useful when working with large data structures like structs, allowing you to modify the original struct without copying the entire object. 74 | 75 | package main 76 | 77 | import "fmt" 78 | 79 | type Person struct { 80 | name string 81 | age int 82 | } 83 | 84 | func updatePerson(p *Person) { 85 | p.age = 30 // Modify the original struct 86 | } 87 | 88 | func main() { 89 | person := Person{name: "John", age: 25} 90 | fmt.Println("Before:", person) // Output: Before: {John 25} 91 | 92 | updatePerson(&person) // Pass the address of the struct 93 | fmt.Println("After:", person) // Output: After: {John 30} 94 | } 95 | 96 | Explanation: 97 | updatePerson takes a pointer to a Person struct (p *Person). 98 | Inside the function, p.age = 30 modifies the original struct's age field. 99 | The changes are reflected in person because its address was passed to the function. 100 | 101 | 102 | Benefits of Pointers in Coding: 103 | 1.Efficiency: Pointers avoid copying large data structures, improving performance, especially when passing large structs, arrays, or slices to functions. 104 | 105 | 2.Memory Management: Pointers allow you to work directly with memory addresses, which can be more efficient in terms of memory usage in some cases. 106 | 107 | 3.Pass by Reference: Functions can modify original variables using pointers, which is useful when you want to change the caller’s variable directly. 108 | 109 | 4.Avoid Redundant Data: Pointers help avoid copying data unnecessarily, which can be useful when working with large collections or objects. 110 | 111 | When to Use Pointers: 112 | When you need to modify the original value passed to a function. 113 | When you want to avoid copying large data structures. 114 | When you want to maintain the same memory reference across function calls. 115 | 116 | When to Avoid Pointers: 117 | For small data types like integers, where copying is negligible and pointers would add unnecessary complexity. 118 | When you don’t need to modify the original value (pass by value works fine in these cases). 119 | 120 | -------------------------------------------------------------------------------- /scope/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /* 4 | ! Scope means visibility. 5 | * the scope or the lifetime of a variable is the interval of time during wh 6 | */ 7 | 8 | import ( 9 | "fmt" 10 | // import "fmt" // this is error 11 | 12 | f "fmt" 13 | ) 14 | 15 | // it permitted in go 16 | 17 | const done = false // package scope 18 | 19 | var b int = 10 // if i am not use this variable there is no error 20 | // it can be used also in other files of the same package 21 | 22 | func main() { 23 | 24 | var task = "running" // local (block) scope 25 | 26 | fmt.Println(task, done) 27 | const done = true // local scope 28 | f.Printf("done in main() is %v\n", done) // it permitted 29 | 30 | fun() // done in fun(): false 31 | f.Println("i am using the fmt alias hear") 32 | 33 | } 34 | 35 | func fun() { 36 | fmt.Printf("done in fun(): %v\n", done) // this done from package scope 37 | a := 10 // if i am not use a varibale it will return error unused variable 38 | _ = a // the blank identifire is represent by the underscore charactor and can be used to mute the compile time error returned 39 | 40 | } 41 | -------------------------------------------------------------------------------- /scope/note.txt: -------------------------------------------------------------------------------- 1 | % --------------------Scopes In Go ---------------------- 2 | 3 | - 1. scope means visibility 4 | - 2. The scope or the lifetime of a variable is the interval of time during which it exist as the program excutes. 5 | - 3. A name cannot be declared again in the same scope ( for example a function in the package scope ), but it declear in another scopes. 6 | 7 | in go there are 3 scopes: 8 | 1. package scope 9 | 2. file scope 10 | 3. block(local) scope 11 | 12 | example 13 | 14 | package main 15 | 16 | import "fmt" // file scope 17 | 18 | const done = false // package scope 19 | 20 | func main(){ 21 | x:= 10 // local (block) scope 22 | fmt.Println(x) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /slice/aslice backing array/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | 6 | 7 | } 8 | -------------------------------------------------------------------------------- /slice/aslice backing array/note.txt: -------------------------------------------------------------------------------- 1 | Slice Baking (Underlying) Array 2 | __________________________________________________________________________________________ 3 | 4 | * when creating a slice, behind the scenes Go creates a hidden array called Baking Array. 5 | * The baking array stores the elements, not the slice 6 | * Go impliments a slice as a data structure called slice header. 7 | 8 | Slice Header contains 3 fields: 9 | 10 | 1. The address of the baking array (Pointer) 11 | 2. The length of the slice len() return it 12 | 3. The capacity of the slice cap() return it. 13 | 14 | * slice Header is the rentime representation of a slice. 15 | * a nil slice does't a have baking arrayecho 16 | 17 | 18 | Syntax for Creating Slices with Length and Capacity 19 | 20 | Using make function: The make function allows you to create a slice with a specified length and capacity. 21 | 22 | slice := make([]T, length, capacity) 23 | slice := make([]int, 3, 5) 24 | 25 | mySlice := make([]string, 3, 5) 26 | 27 | // Access the length and capacity 28 | fmt.Println("Slice:", mySlice) // Output: ["" "" ""] 29 | fmt.Println("Length:", len(mySlice)) // Output: 3 30 | fmt.Println("Capacity:", cap(mySlice)) // Output: 5 -------------------------------------------------------------------------------- /slice/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var cities []string 7 | fmt.Println("Cities is equal to nil", cities == nil) //Cities is equal to nil true 8 | fmt.Printf("cities %#v\n", cities) //cities []string(nil) 9 | fmt.Println(len(cities)) //0 10 | 11 | //cities[0] = "ABC" // this is error panic: runtime error: index out of range [0] with length 0 12 | 13 | // keep in mind that the elements have a position or index that starts from zero not one 14 | 15 | numbers := []int{2, 3, 4, 5} // right side of eqil = is the slice literal 16 | fmt.Println(numbers) // [2 3 4 5] 17 | // another way to clreate slice is to use the make function 18 | 19 | num := make([]int, 2) 20 | fmt.Printf("%#v\n", num) // []int{0, 0} 21 | 22 | type names []string 23 | 24 | friends := names{"manish", "raj"} 25 | fmt.Println("my best friends is ", friends) //y best friends is [manish raj] 26 | friends[0] = "priya" 27 | fmt.Println("my best friends is ", friends) //y best friends is [priya raj] 28 | 29 | // number slice 30 | for index, value := range numbers { 31 | fmt.Printf("index %d value %d\n", index, value) 32 | } 33 | 34 | var n []int = numbers 35 | // n = numbers 36 | // `n = numbers` is assigning the slice `numbers` to the slice `n`. This means that both `n` and 37 | // `numbers` will refer to the same underlying array. Any changes made to the elements of the slice 38 | // through one variable will be reflected in the other variable as well since they are pointing to the 39 | // same data. 40 | fmt.Println(n) 41 | 42 | var mn []int 43 | fmt.Println(mn == nil) //true 44 | 45 | mk := []int{} 46 | fmt.Println(mk == nil) //false 47 | 48 | a, b := []int{1, 2, 3}, []int{1, 2, 3} 49 | //fmt.Println(a == b) // this is error // slice only compire nil 50 | 51 | var eq bool = true 52 | 53 | a = nil 54 | 55 | if len(a) != len(b) { 56 | eq = false 57 | } 58 | 59 | for i, valueA := range a { 60 | if valueA != b[i] { 61 | 62 | eq = false 63 | break 64 | } 65 | 66 | } 67 | 68 | if eq { 69 | fmt.Println("a and b slice are equal") 70 | } else { 71 | fmt.Println("a and b slice are not equal") 72 | } 73 | 74 | // How to append slice 75 | // append does't modify the initial slice it return a brand the new one; 76 | nm := []int{2, 3} 77 | nm = append(nm, 4) 78 | fmt.Println(nm) // [2 3 4] 79 | // other example 80 | 81 | nms := []int{3, 4, 5, 6} 82 | nms = append(nms, 10, 11, 12) 83 | fmt.Println(nms) 84 | 85 | nn := []int{10, 20} 86 | nm = append(nm, nn...) 87 | fmt.Println(nm) //[2 3 4 10 20] 88 | // The append() function returns-iohg 89 | 90 | //Copy function 91 | // the copy function does't always clone or dublicate a slice 92 | src := []int{10, 20, 30, 40} 93 | dist := make([]int, len(src)) 94 | q := copy(dist, src) 95 | fmt.Println(src, dist, q) 96 | 97 | /* 98 | Explanation: 99 | src := []int{10, 20, 30, 40}: The src slice is initialized with 4 elements: [10, 20, 30, 40]. 100 | 101 | dist := make([]int, len(src)): The dist slice is created with a length equal to src, but all elements are initialized to 0. So initially, dist = [0, 0, 0, 0]. 102 | 103 | q := copy(dist, src): The copy() function copies elements from the src slice into the dist slice. Since both slices have the same length, all 4 elements will be copied. The copy() function returns the number of elements copied, which in this case is 4. 104 | 105 | fmt.Println(src, dist, q): This prints: 106 | 107 | The original src slice. 108 | The dist slice, which now contains the copied elements from src. 109 | The value of q, which represents the number of elements copied. 110 | 111 | / description/ 112 | src := []int{10, 20, 30, 40} // Initialize a slice 'src' with 4 elements 113 | dist := make([]int, len(src)) // Create a 'dist' slice with the same length as 'src', but all elements initialized to 0 114 | q := copy(dist, src) // Copy elements from 'src' to 'dist'. 'q' holds the number of elements copied 115 | fmt.Println(src, dist, q) // Print 'src', 'dist', and the number of elements copied ('q') 116 | */ 117 | 118 | //Slice Expressions 119 | // slice does't modify the array or slice, it return a new one. 120 | ab := [5]int{1, 2, 3, 4, 5} 121 | // aa[start:stop] 122 | bb := ab[1:3] 123 | fmt.Printf("%v, %T\n", bb, bb) // [2 3] []int 124 | // we notice that slicing an array returns a slice , not array 125 | q1 := []int{1, 2, 3, 4, 5, 6} 126 | q2 := q1[1:3] 127 | fmt.Printf("%v, %T\n", q2, q2) // [2 3] 128 | fmt.Println(q1[2:]) //[3 4 5 6] same as q1[2:len(q1)] 129 | fmt.Println(q1[:3]) //[1 2 3] same as q1[0:3] 130 | fmt.Println(q1[:]) //[1 2 3 4 5 6] same as q1[0:len(s1)] 131 | // fmt.Println(q1[:100]) // this is error index out of bound 132 | q1 = append(q1[:4], 100) 133 | fmt.Println(q1) //[1 2 3 4 100] 134 | 135 | } 136 | -------------------------------------------------------------------------------- /slice/note.txt: -------------------------------------------------------------------------------- 1 | Array 2 | - Has a fixed length defined at compile time 3 | - The length of an array is part of its type, defined at compile time and can not be changed 4 | - By defalut an uninitialized array has all element equal to zero 5 | 6 | Slice 7 | - Has a dynamic length (it can shink or grow) 8 | - The length of a slice is not part of its type, it is determined at runtime 9 | - an uninitialized slice is equal to nil (its zero value is nil) 10 | 11 | -------------------------------------------------------------- 12 | * both slice and an array can contain only same type of elements 13 | * we can create a keyed slice like keyed array 14 | 15 | In Go, list := []int{1, 2, 3, 4} is a slice, not an array. 16 | 17 | Here's the difference between a slice and an array in Go: 18 | 19 | Array: An array has a fixed size, which is part of its type, and it cannot be resized. For example: 20 | 21 | 22 | var arr [4]int = [4]int{1, 2, 3, 4} // This is an array with a fixed length of 4 23 | Slice: A slice is a dynamically sized, flexible view into the elements of an array. It does not include the size in its type, and you can append or modify it as needed. For example: 24 | 25 | 26 | list := []int{1, 2, 3, 4} // This is a slice 27 | Since your declaration omits the length ([]int{}), list is a slice. 28 | 29 | In the declaration list := [...]int{2, 3, 4, 5}, this is an array, not a slice. 30 | 31 | The [...] syntax in Go is used to define an array where the length is inferred from the number of elements provided in the literal. In this case, the array has a fixed size of 4 elements. 32 | 33 | Explanation: 34 | Array: The type [...]int{2, 3, 4, 5} means the array has a length of 4, and it's determined by the number of elements between the curly braces. This is a fixed-length array. 35 | 36 | 37 | list := [...]int{2, 3, 4, 5} // Array of length 4 38 | Slice: A slice would not specify the length or use [...]. For example: 39 | 40 | 41 | list := []int{2, 3, 4, 5} // This would be a slice 42 | Since your code uses [...], list is an array. 43 | 44 | 45 | 46 | Feature Array Slice 47 | Size Fixed size, determined at compile time. Dynamic size, can grow or shrink. 48 | 49 | Syntax var arr [4]int = [4]int{1, 2, 3, 4} var slice []int = []int{1, 2, 3, 4} 50 | Length Length is part of the type (e.g., [4]int). Length is not part of the type (e.g., []int). 51 | Capacity apacity is always equal to length. Capacity can be larger than the current length. 52 | Memory Allocation Allocates memory for all elements, even if unused. Uses dynamic arrays under the hood, reallocating as needed. 53 | Resizable Cannot change size once created. Can be resized using functions like append(). 54 | Reference Behavior Direct value type (copy of array). Reference type, referencing the underlying array. 55 | Efficiency More memory-efficient if fixed size is known. More flexible and convenient for variable-sized data. 56 | Passing to Functions Passed by value (copy of the array). Passed by reference (points to the underlying array). 57 | Built-in Functions No built-in functions like append, copy. Has built-in functions such as append, copy, len, cap. 58 | 59 | 60 | Key Features of Slices: 61 | Dynamic size: The size of a slice can change as elements are added or removed. 62 | 63 | Underlying array: A slice points to a portion of an underlying array. 64 | 65 | Capacity and length: Slices have both length (the number of elements in the slice) and capacity (the total number of elements the underlying array can hold). 66 | 67 | package main 68 | 69 | import "fmt" 70 | 71 | func main() { 72 | // Create a slice with 3 elements 73 | nums := []int{10, 20, 30} // Slice literal (dynamic array) 74 | 75 | fmt.Println("Initial slice:", nums) // Output: [10, 20, 30] 76 | 77 | // Append new elements to the slice 78 | nums = append(nums, 40, 50) 79 | fmt.Println("After appending:", nums) // Output: [10, 20, 30, 40, 50] 80 | 81 | // Slice an existing slice (create a sub-slice) 82 | subSlice := nums[1:4] // Slicing from index 1 to 3 (not including 4) 83 | fmt.Println("Sub-slice:", subSlice) // Output: [20, 30, 40] 84 | 85 | // Modify an element of the sub-slice (this affects the original slice) 86 | subSlice[0] = 25 87 | fmt.Println("Modified sub-slice:", subSlice) // Output: [25, 30, 40] 88 | fmt.Println("Original slice after modification:", nums) // Output: [10, 25, 30, 40, 50] 89 | 90 | // Use the built-in `len` and `cap` functions 91 | fmt.Println("Length of slice:", len(nums)) // Output: 5 92 | fmt.Println("Capacity of slice:", cap(nums)) // Output: 6 (capacity can be larger than the length) 93 | } 94 | 95 | Explanation: 96 | Slice Literal: nums := []int{10, 20, 30} creates a slice with 3 elements. The underlying array is automatically managed by Go. 97 | Appending: append(nums, 40, 50) adds two new elements to the slice, dynamically increasing its size. 98 | Slicing: subSlice := nums[1:4] creates a sub-slice from the second to the fourth element of nums. The sub-slice is a reference to the same underlying array, so changes in the sub-slice affect the original slice. 99 | Modifying a Sub-slice: Changing subSlice[0] updates the original nums slice, showing the reference behavior of slices. 100 | Length and Capacity: len(nums) gives the current number of elements, and cap(nums) gives the capacity (which can be larger than the length due to underlying array resizing). 101 | Key Points About Slices: 102 | Slicing: You can create a new slice from an existing slice using the slicing operator slice[low:high]. 103 | Capacity: Slices may have extra capacity. As you append elements, Go automatically resizes the underlying array when necessary. 104 | Zero Value: The zero value of a slice is nil, which behaves like a slice with length and capacity 0. 105 | 106 | 107 | Recap of Key Functions: 108 | append(): Adds elements to a slice, dynamically growing it. 109 | copy(): Copies elements from one slice to another. 110 | len(): Returns the current number of elements in the slice. 111 | cap(): Returns the total capacity of the slice, or how many elements it can hold before resizing. 112 | 113 | Here’s a simple yet powerful example to supercharge your Go skills with slices👇: 114 | 115 | tasks := []string{"Design", "Develop", "Test"} 116 | tasks = append(tasks, "Deploy") 117 | backupTasks := make([]string, len(tasks)) 118 | copy(backupTasks, tasks) 119 | fmt.Println(tasks, backupTasks) 120 | 121 | 122 | -------------------------------------------------------------------------------- /struct/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | // 1. Defining a struct 9 | type Person struct { 10 | Name string `json:"name"` // 6. Struct tags (for JSON encoding) 11 | Age int `json:"age"` 12 | } 13 | 14 | // 5. Embedding in Struct (Composition) 15 | type Employee struct { 16 | Person // Embedding Person struct 17 | Position string 18 | Salary float64 19 | } 20 | 21 | // 4. Pointer to Struct (function to update age) 22 | func UpdateAge(p *Person, newAge int) { 23 | p.Age = newAge 24 | } 25 | 26 | func main() { 27 | // 2. Initializing a Struct (different ways) 28 | 29 | // Using field names 30 | person1 := Person{Name: "John", Age: 30} 31 | 32 | // Without field names (order matters) 33 | person2 := Person{"Alice", 25} 34 | 35 | // Zero value initialization 36 | var person3 Person // Fields will have default values (Name: "", Age: 0) 37 | 38 | // 3. Accessing and Modifying Struct Fields 39 | fmt.Println("Initial Name:", person1.Name) // Accessing field 40 | person1.Age = 31 // Modifying field 41 | fmt.Println("Updated Age:", person1.Age) 42 | 43 | // 4. Passing Struct by Reference 44 | fmt.Println("Before UpdateAge:", person2.Age) 45 | UpdateAge(&person2, 26) // Passing a pointer to the struct 46 | fmt.Println("After UpdateAge:", person2.Age) 47 | 48 | // 5. Embedding a Struct (Composition) 49 | employee := Employee{ 50 | Person: Person{Name: "Bob", Age: 40}, 51 | Position: "Manager", 52 | Salary: 75000.50, 53 | } 54 | fmt.Printf("Employee: %s, Position: %s, Salary: %.2f\n", employee.Name, employee.Position, employee.Salary) 55 | 56 | // 6. Struct Tags (JSON Encoding Example) 57 | jsonData, _ := json.Marshal(person1) // Marshal person1 to JSON 58 | fmt.Println("JSON Output:", string(jsonData)) 59 | 60 | // 7. Zero Value Struct 61 | fmt.Printf("Zero Value Struct: %+v\n", person3) // Print zero-initialized struct 62 | 63 | // 8. Comparing Structs 64 | person4 := Person{Name: "John", Age: 31} 65 | if person1 == person4 { 66 | fmt.Println("person1 and person4 are equal!") 67 | } else { 68 | fmt.Println("person1 and person4 are not equal.") 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /struct/note.txt: -------------------------------------------------------------------------------- 1 |

    What is struct

    2 | 3 | -> struct (short for "structure") is a composite data type that groups together different variables under a single name.
    4 | ->Each of these variables can be of different types, and they are called fields of the struct.
    5 | -> In Go, Struct are one of the most powerful and commonly used data type
    6 | -> Struct allow you to group related data together, making your code more orgnized and easy to work with.
    7 | 8 | type Person struct { 9 | Name string 10 | Age int 11 | Address string 12 | } 13 | 14 | main 15 | person1 := Person{ 16 | Name: "John Doe", 17 | Age: 30, 18 | Address: "123 Main Street", 19 | } 20 | 21 | // Accessing the fields 22 | fmt.Println("Name:", person1.Name) 23 | fmt.Println("Age:", person1.Age) 24 | fmt.Println("Address:", person1.Address) 25 | 26 | // Modifying a field 27 | person1.Age = 31 28 | fmt.Println("Updated Age:", person1.Age) 29 | 30 | A struct is a callection of fields, where each field has its own type.
    31 | it's similar to classes in other programming language, but without method attached. 32 | 33 |

    Syntex

    34 | 35 | type Person struct { 36 | Name string 37 | Age int 38 | } 39 | 40 | 41 | type Event struct { 42 | ID int64 // id of the event 43 | Name string `json:"name" binding:"required"` // name of the event 44 | Description string `json:"description" binding:"required"` 45 | Location string `json:"location" binding:"required"` // location of the event 46 | StartTime time.Time `json:"startTime" binding:"required"` // start time of the event 47 | UserID int64 `json:"user_id"` 48 | } 49 | 50 |

    Anonymous Structs

    51 | - Go also allow the use of anonymous structs, which does't require pre-defined type
    52 | - You can define and use a struct without explicitly creating a named type. This is useful for quick one-off uses where you don’t need to reuse the struct elsewhere.
    53 | 54 | **example** 55 | person := struct { 56 | Name string 57 | Age int 58 | }{ 59 | Name: "Alice", 60 | Age: 25, 61 | } 62 | 63 | fmt.Println(person.Name) // Output: Alice 64 | 65 | **3. Embedded Struct (Struct Composition)** 66 | 67 | Go doesn’t support inheritance, but you can achieve a similar effect using struct embedding. This allows one struct to contain another, effectively reusing fields from the embedded struct.
    68 | 69 | **Example** 70 | type Address struct { 71 | City string 72 | State string 73 | } 74 | 75 | type Person struct { 76 | Name string 77 | Age int 78 | Address // Embedded struct 79 | } 80 | 81 | func main() { 82 | person := Person{ 83 | Name: "John", 84 | Age: 30, 85 | Address: Address{ 86 | City: "New York", 87 | State: "NY", 88 | }, 89 | } 90 | 91 | fmt.Println(person.City) // Output: New York 92 | fmt.Println(person.State) // Output: NY 93 | } 94 | 95 | 96 | **4. Struct with Methods** 97 | -Go allows you to associate methods with a struct, enabling you to create behavior associated with the data within the struct.
    98 | 99 | type Person struct { 100 | Name string 101 | Age int 102 | } 103 | 104 | // Method associated with the Person struct 105 | func (p Person) Greet() { 106 | fmt.Printf("Hello, my name is %s.\n", p.Name) 107 | } 108 | 109 | func main() { 110 | person := Person{Name: "Bob", Age: 25} 111 | person.Greet() // Output: Hello, my name is Bob. 112 | } 113 | 114 | **5. Pointer to a Struct** 115 | -Go allows you to use pointers with structs. This is particularly useful for modifying the struct's data or avoiding the cost of copying large structs.
    116 | 117 | type Person struct { 118 | Name string 119 | Age int 120 | } 121 | 122 | func modifyPerson(p *Person) { 123 | p.Age = 30 124 | } 125 | 126 | func main() { 127 | person := Person{Name: "Alice", Age: 25} 128 | modifyPerson(&person) 129 | fmt.Println(person.Age) // Output: 30 130 | } 131 | 132 | **6. Tagged Structs** 133 | You can add tags to struct fields, often used in conjunction with serialization (like json, xml, etc.). These tags help control how data is marshaled or unmarshaled.
    134 | 135 | package main 136 | 137 | import ( 138 | "encoding/json" 139 | "fmt" 140 | ) 141 | 142 | // User struct with a JSON tag for username 143 | type User struct { 144 | Username string `json:"username"` // JSON tag 145 | } 146 | 147 | func main() { 148 | // Create an instance of User 149 | user := User{ 150 | Username: "john_doe", 151 | } 152 | 153 | // Marshal the struct to JSON 154 | jsonData, err := json.Marshal(user) 155 | if err != nil { 156 | fmt.Println("Error marshaling to JSON:", err) 157 | return 158 | } 159 | 160 | // Print the JSON output 161 | fmt.Println(string(jsonData)) // Output: {"username":"john_doe"} 162 | } 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /variable/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | todo - A variable is a name for a memory location where a value od a spacific type is stored 7 | ! in Go a varibale belongs and its created at runtime. 8 | ? A decleared variable must be used or we get an error 9 | ! _ is a blank identifier and mutes the compile time error returend variables. 10 | 11 | todo ------DECLEARING VARIABLE------------- 12 | ? var x int =7 13 | ! var s1 string 14 | ? s1 = "Learning Go" 15 | 16 | todo 2. Using the short declaration Operator (:=) 17 | ? age := 21 18 | */ 19 | 20 | func main() { 21 | var x int = 7 22 | var y = "manish" 23 | lastname := "kumar" 24 | 25 | car, cost := "BMW", 570000 // multipal variable declaration 26 | fmt.Println(car, cost) 27 | 28 | var opend = false 29 | opend, file := true, "new.txt" 30 | _, _ = opend, file 31 | fmt.Println("this is variable", x, y, lastname) 32 | 33 | // multipal declaration 34 | 35 | var ( 36 | salary float64 37 | firstname string 38 | gender bool 39 | ) 40 | 41 | fmt.Println(salary, firstname, gender) 42 | 43 | var a, b, c int 44 | fmt.Println(a, b, c) 45 | // multipal assignment 46 | 47 | var i, j int 48 | i, j = 10, 20 49 | fmt.Println(i, j) 50 | 51 | //swap two number 52 | 53 | j, i = i, j 54 | fmt.Println(i, j) 55 | 56 | sum := 5 + 3.5 57 | fmt.Println(sum) 58 | 59 | // you can not assign float value in int 60 | 61 | var one = 4 62 | var two = 7.5 63 | 64 | // one = two you cant not siign float value in int 65 | // one = 7.5 // error: cannot use b (type float64) as 66 | one = int(two) 67 | fmt.Println(one, two) 68 | 69 | // ! GO Zero Values 70 | // ?GO has zero values for all types. Zero values are the default values assigned to variables when 71 | // they are declared without an explicit initial value. 72 | // Zero values are as follows: 73 | // !1. Boolean: false 74 | // !2. Numeric: 0 75 | // !3. string ""(empty string) 76 | // !4. Complex: 0+0i 77 | // !5. pointer type : nil 78 | 79 | // ? Go is a statically and strong typed programming language 80 | 81 | var aa int = 10 82 | var bb = 15.5 83 | cc := "Go Pro" 84 | 85 | _, _, _ = aa, bb, cc 86 | 87 | fmt.Println(aa, bb, cc) 88 | 89 | /* 90 | ! -------------NAMING CONVENTION--------------------------- 91 | 92 | todo = Naming (variable, function, packages) Conventions is GO 93 | ? nameing Convention are important for code readability and maintainability. 94 | * Names start with a letter or an underscore(_) 95 | * Case Matter: quickSort and QuickSort are diffrent variable 96 | * Go keywords (25) can not be used as names 97 | * Use the first letters of the words 98 | 99 | 100 | !2. Variable Names 101 | * Use camelCase for variables and function names. 102 | * Variable names should be concise but descriptive enough to understand the intent. Avoid one-letter names unless in small scopes like loop indices. 103 | *var userName string // Good 104 | ! var uName string // Avoid (too unclear) 105 | * var x int // Acceptable in small contexts like loops 106 | 107 | ! 1. Package Names 108 | *Package names should be short, lowercase, and should not contain underscores or mixed case. 109 | ?package math // Good 110 | ?package http // Good 111 | !package utilities // Avoid 112 | !package fileHelper // Avoid 113 | */ 114 | 115 | 116 | } 117 | --------------------------------------------------------------------------------