├── 01-variables └── main.go ├── 02-types ├── 02.1-operators │ └── main.go ├── 02.2-strings │ └── main.go └── main.go ├── 03-constants └── main.go ├── 04-functions └── main.go ├── 05-packages ├── api │ ├── model │ │ └── user.go │ └── server.go ├── go.mod └── main.go ├── 06-if-statement └── main.go ├── 07-loops └── main.go ├── 08-switch └── main.go ├── 09-arrays └── main.go ├── 10-slices └── main.go ├── 11-variadic-functions └── main.go ├── 12-maps └── main.go ├── 13-pointers └── main.go ├── 14-structs ├── go.mod ├── main.go └── model │ └── user.go ├── 15-methods └── main.go ├── 16-interfaces └── main.go ├── 17-goroutines └── main.go ├── 18-channels └── main.go ├── 19-buffered-channels └── main.go ├── 20-select └── main.go ├── 21-mutex └── main.go ├── 22-defer └── main.go ├── 23-error-handling └── main.go ├── 24-custom-errors └── main.go ├── 25-files ├── main.go └── test.txt └── README.md /01-variables/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // // Declaring variables 7 | var a int 8 | var b string 9 | fmt.Println(a) 10 | fmt.Println(b) 11 | 12 | // Initializing Variables 13 | a = 10 //assignment 14 | fmt.Println(a) 15 | 16 | // Creating and initializing variables 17 | var c = 10 18 | var d = "topdemy.ir" 19 | fmt.Println(c) 20 | fmt.Println(d) 21 | 22 | // Declaring multiple variables 23 | var e, f int 24 | fmt.Println(e, f) 25 | e = 10 26 | f = 100 27 | fmt.Println(e, f) 28 | // Creating and initializing multiple variables 29 | var g, h = 10, 100 30 | fmt.Println(g, h) 31 | 32 | // Variable Declaration Block 33 | var ( 34 | i = 10 35 | j = "mohammad" 36 | k = 1000 37 | ) 38 | 39 | fmt.Println(i, j, k) 40 | 41 | //Short variable declaration 42 | var l int 43 | var m int 44 | l, m, n := 10, 20, 30 45 | fmt.Println(l, m, n) 46 | } 47 | -------------------------------------------------------------------------------- /02-types/02.1-operators/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // x + y 7 | // x - y 8 | // x * y 9 | // x / y 10 | // x % y 11 | 12 | a := -88 13 | b := 85 14 | c := 15 15 | fmt.Println(a + b) 16 | fmt.Println(c + b) 17 | fmt.Println(c * b) 18 | fmt.Println(b % c) 19 | 20 | c += 10 //=> c = c + 10 21 | c -= 10 //=> c = c - 10 22 | c *= 10 //=> c = c * 10 23 | c /= 10 //=> c = c / 10 24 | c %= 10 //=> c = c % 10 25 | 26 | } 27 | -------------------------------------------------------------------------------- /02-types/02.2-strings/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func printCh(s string) { 6 | fmt.Println(s) 7 | for i := 0; i < len(s); i++ { 8 | fmt.Printf("%c ", s[i]) 9 | } 10 | } 11 | 12 | func main() { 13 | fmt.Print("hi", "mohmmad") 14 | fmt.Print("aaa") 15 | fmt.Println("hi", "mohmmad") 16 | fmt.Println("aaa") 17 | fmt.Printf("hi %s test", "mohmmad") 18 | // fmt.Printf("hi %s %d %T %f %v test",) 19 | 20 | var a string = "test" 21 | b := "test2" 22 | 23 | fmt.Println(a == b) 24 | 25 | c := a + " " + b 26 | 27 | fmt.Println(c) 28 | 29 | printCh(a) 30 | 31 | d := []byte{121, 34, 213, 65, 10} 32 | str := string(d) 33 | fmt.Println(str) 34 | } 35 | -------------------------------------------------------------------------------- /02-types/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | /* 10 | . bool 11 | . string 12 | . Numeric Types 13 | uint8 8 bit unsigned integers (0 to 255) 14 | uint16 16 bit unsigned integers (0 to 65535) 15 | uint32 32 bit unsigned integers (0 to 4294967295) 16 | uint64 64 bit unsigned integers (0 to 18446744073709551615) 17 | uint 32 or 64 bit unsigned integers depending on the underlying architecture 18 | 19 | int8 8 bit signed integers (-128 to 127) 20 | int16 16 bit signed integers integers (-32768 to 32767) 21 | int32 32 bit signed integers (-2147483648 to 2147483647) 22 | int64 64 bit signed integers (-9223372036854775808 to 9223372036854775807) 23 | int represents 32 or 64 bit integers depending on the underlying architecture 24 | 25 | float32 32 bit floating point numbers 26 | float64 64 bit floating point numbers 27 | complex64 complex numbers with float32 real and imaginary parts 28 | complex128 complex numbers with float64 real and imaginary parts 29 | 30 | byte alias for uint8 31 | rune alias for int32 32 | */ 33 | 34 | // bool 35 | var a bool = true 36 | var b bool = false 37 | c := a || b 38 | d := a && b 39 | fmt.Println(a) 40 | fmt.Println(b) 41 | fmt.Println(c) 42 | fmt.Println(d) 43 | 44 | // string 45 | var e string = "test1" 46 | var f string = "test2" 47 | g := e + " " + f 48 | fmt.Println(g) 49 | 50 | // int 51 | var i int = 32 52 | j := 90 53 | 54 | fmt.Println("value of a is ", i, "and b is ", j) 55 | fmt.Printf("type of a is %T, size of a is %d bytes", i, unsafe.Sizeof(i)) 56 | 57 | // uint 58 | var k uint = 32 59 | l := 90 60 | 61 | fmt.Println("value of a is ", k, "and b is ", l) 62 | fmt.Printf("type of a is %T, size of a is %d bytes", k, unsafe.Sizeof(k)) 63 | 64 | // float32 65 | var m, n float64 = 5.32, 1.12 66 | fmt.Println("value of a is ", m, "and b is ", n) 67 | fmt.Printf("type of a is %T, size of a is %d bytes", m, unsafe.Sizeof(m)) 68 | 69 | //complex 70 | o := complex(5, 6) 71 | p := 8 + 33i 72 | sum := o + p 73 | fmt.Println("value of a is ", sum) 74 | 75 | // T(v) 76 | // a := 80 77 | // b := 80.1 78 | // sum := float64(a) + b 79 | // fmt.Println(sum) 80 | } 81 | -------------------------------------------------------------------------------- /03-constants/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | // Declaring a constant 9 | const a = "test1" 10 | fmt.Println(a) 11 | 12 | // Declaring a group of constants 13 | const ( 14 | c = 1 15 | d = 2 16 | e = 3 17 | ) 18 | 19 | // The value of a constant should be known at compile time 20 | // var a = math.Sqrt(4) 21 | // fmt.Println(a) 22 | // const b = math.Sqrt(4) 23 | // fmt.Println(b) 24 | 25 | // Typed and Untyped Constants 26 | const name bool = true 27 | var f = name 28 | fmt.Println(name, f) 29 | } 30 | -------------------------------------------------------------------------------- /04-functions/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | price, n := 100, 2 7 | c1, c2 := sum(price, n) 8 | // Blank Identifier 9 | c3, _ := sum(price, n) 10 | fmt.Println(c1, c2) 11 | fmt.Println(c3) 12 | } 13 | 14 | // Function declaration 15 | 16 | // func functionname(parametername type) returntype { 17 | //function body 18 | // } 19 | 20 | // Sample Function 21 | func sum(price, n int) (int, int) { 22 | a := price * n 23 | b := price + n 24 | return a, b 25 | } 26 | -------------------------------------------------------------------------------- /05-packages/api/model/user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "fmt" 4 | 5 | func NewUser() { 6 | fmt.Println("user") 7 | } 8 | -------------------------------------------------------------------------------- /05-packages/api/server.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "fmt" 4 | 5 | func Print() { 6 | fmt.Println("api") 7 | } 8 | -------------------------------------------------------------------------------- /05-packages/go.mod: -------------------------------------------------------------------------------- 1 | module learn 2 | 3 | go 1.23.0 4 | -------------------------------------------------------------------------------- /05-packages/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "learn/api" 5 | _ "learn/api/model" 6 | ) 7 | 8 | func main() { 9 | api.Print() 10 | } 11 | -------------------------------------------------------------------------------- /06-if-statement/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // If statement syntax 8 | number := 10 9 | 10 | if number == 2 { 11 | fmt.Println("number 2") 12 | } else { 13 | fmt.Println("number :", number) 14 | } 15 | 16 | // If else statement 17 | num := 10 18 | var code int 19 | 20 | if num < 5 { 21 | code = 10 22 | } else if num > 5 && num < 10 { 23 | code = 20 24 | } else { 25 | code = 30 26 | } 27 | fmt.Println(code) 28 | 29 | // If with assignment 30 | var price int 31 | 32 | if age := 10; age < 5 { 33 | price = 10 34 | } else if age > 5 && age < 10 { 35 | price = 20 36 | } else { 37 | price = 30 38 | } 39 | 40 | fmt.Println(price) 41 | } 42 | -------------------------------------------------------------------------------- /07-loops/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // for loop syntax 7 | for i := 1; i < 5; i++ { 8 | fmt.Println(i) 9 | } 10 | 11 | // break 12 | for i := 1; i < 5; i++ { 13 | if i > 3 { 14 | break 15 | } 16 | fmt.Println(i) 17 | } 18 | 19 | // continue 20 | for i := 1; i < 5; i++ { 21 | if i == 3 { 22 | continue 23 | } 24 | fmt.Println(i) 25 | } 26 | 27 | // infinite loop 28 | for { 29 | fmt.Println("hello") 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /08-switch/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // switch 8 | 9 | a := 5 10 | switch a { 11 | case 1: 12 | fmt.Println(a) 13 | 14 | case 2: 15 | fmt.Println(a) 16 | 17 | case 3: 18 | fmt.Println(a) 19 | 20 | case 4: 21 | fmt.Println(a) 22 | 23 | // Duplicate cases are not allowed 24 | // case 4: 25 | // fmt.Println(num) 26 | case 6: 27 | fmt.Println(a) 28 | default: 29 | fmt.Println(5) 30 | } 31 | 32 | // Multiple expressions in case 33 | number := 5 34 | switch number { 35 | case 1, 2, 3, 4, 6: 36 | fmt.Println(number) 37 | 38 | default: 39 | fmt.Println("number false") 40 | } 41 | 42 | // Expressionless switch 43 | num := 10 44 | var code int 45 | switch { 46 | case num < 5: 47 | code = 10 48 | case num > 5 && num < 10: 49 | code = 20 50 | default: 51 | code = 30 52 | } 53 | fmt.Println(code) 54 | } 55 | -------------------------------------------------------------------------------- /09-arrays/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // Arrays 7 | var a [3]int 8 | a[0] = 12 9 | a[1] = 22 10 | a[2] = 30 11 | fmt.Println(a) 12 | 13 | b := [...]int{10, 20, 30, 40, 50, 60} 14 | fmt.Println(b) 15 | 16 | c := [...]int{10, 20, 30, 40, 50, 60} 17 | d := c 18 | d[0] = 100 19 | fmt.Println(c) 20 | fmt.Println(d) 21 | 22 | e := [...]int{10, 20, 30, 40, 50, 60} 23 | fmt.Println("before", e) 24 | change(e) 25 | fmt.Println("after", e) 26 | 27 | f := [...]int{10, 20, 30, 40, 50, 60} 28 | fmt.Println("lenght", len(f)) 29 | 30 | g := [...]int{10, 20, 30, 40, 50, 60} 31 | for i := 0; i < len(g); i++ { 32 | fmt.Println("element ", g[i]) 33 | } 34 | for i, v := range g { 35 | fmt.Println(i, v) 36 | } 37 | 38 | for _, v := range g { 39 | fmt.Println(v) 40 | } 41 | 42 | h := [3][2]string{ 43 | {"a", "b"}, 44 | {"c", "d"}, 45 | {"e", "f"}, 46 | } 47 | fmt.Println(h) 48 | 49 | } 50 | 51 | func change(number [6]int) { 52 | number[0] = 200 53 | fmt.Println("in function", number) 54 | } 55 | -------------------------------------------------------------------------------- /10-slices/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // Creating a slice 7 | a := [6]int{80, 78, 56, 55, 23, 10} 8 | var b []int = a[1:4] 9 | fmt.Println(b) 10 | 11 | c := []int{80, 78, 56, 55, 23, 10} 12 | fmt.Println(c) 13 | 14 | // modifying a slice 15 | d := [6]int{80, 78, 56, 55, 23, 10} 16 | var e []int = d[1:4] 17 | fmt.Println("before ", d) 18 | for i := range e { 19 | e[i]++ 20 | } 21 | fmt.Println("after ", e) 22 | 23 | // length and capacity of a slice 24 | f := [6]int{80, 78, 56, 55, 23, 10} 25 | var g []int = f[1:4] 26 | fmt.Println(len(g), cap(g)) 27 | 28 | // creating a slice using make 29 | h := make([]int, 3, 5) 30 | fmt.Println(h) 31 | 32 | // Appending to a slice 33 | i := []string{"a", "b", "c"} 34 | i = append(i, "d") 35 | fmt.Println(i) 36 | 37 | // Passing a slice to a function 38 | j := []int{80, 78, 56, 55, 23, 10} 39 | fmt.Println("befor ", j) 40 | change(j) 41 | fmt.Println("after ", j) 42 | 43 | } 44 | 45 | func change(numbers []int) { 46 | for i := range numbers { 47 | numbers[i] -= 1 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /11-variadic-functions/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // variadic function 7 | numbers := []int{90, 10, 900, 60} 8 | find(10, numbers...) 9 | } 10 | 11 | func find(number int, numbers ...int) { 12 | found := false 13 | for i, v := range numbers { 14 | if v == number { 15 | fmt.Println(number, "found at index", i) 16 | found = true 17 | } 18 | } 19 | 20 | if !found { 21 | fmt.Println(number, "not found") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /12-maps/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // create a map 8 | a := make(map[string]int) 9 | fmt.Println(a) 10 | 11 | // Adding items to a map 12 | b := map[string]int{ 13 | "name": 100, 14 | "test": 123, 15 | } 16 | b["asd"] = 123123 17 | fmt.Println(b) 18 | 19 | // nil map panics 20 | var c map[string]int 21 | c["asd"] = 123123 22 | fmt.Println(c) 23 | 24 | // Retrieving value for a key from a map 25 | d := map[string]int{ 26 | "name": 100, 27 | "test": 123, 28 | } 29 | fmt.Println(d["name"]) 30 | 31 | // Checking if a key exists 32 | if value, ok := d["name"]; ok { 33 | fmt.Println(value, ok) 34 | } else { 35 | fmt.Println(ok) 36 | } 37 | 38 | // Deleting items from a map 39 | e := map[string]int{ 40 | "name": 100, 41 | "test": 123, 42 | } 43 | fmt.Println("before", e) 44 | delete(a, "name") 45 | fmt.Println("after", e) 46 | 47 | // Iterate over all elements in a map 48 | f := map[string]int{ 49 | "name": 100, 50 | "test": 123, 51 | } 52 | 53 | for i, v := range f { 54 | fmt.Println(i, v) 55 | } 56 | 57 | // Maps are reference types 58 | g := map[string]int{ 59 | "name": 100, 60 | "test": 123, 61 | } 62 | 63 | test := g 64 | test["name"] = 99 65 | fmt.Println(g) 66 | } 67 | -------------------------------------------------------------------------------- /13-pointers/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // Declaring pointers 7 | b := 123 8 | var a *int = &b 9 | fmt.Println(a) 10 | 11 | // pointers 12 | c := 123 13 | var d *int 14 | if d == nil { 15 | fmt.Println(d) 16 | d = &c 17 | fmt.Println(d) 18 | } 19 | 20 | // Creating pointers using the new function 21 | e := new(int) 22 | fmt.Println(e) 23 | 24 | // Dereferencing a pointer 25 | f := 123 26 | g := &f 27 | fmt.Println(g) 28 | fmt.Println(*g) 29 | 30 | // Passing pointer to a function 31 | h := 123 32 | fmt.Println(h) 33 | i := &h 34 | change(i) 35 | fmt.Println(h) 36 | } 37 | 38 | // Passing pointer to a function 39 | func change(val *int) { 40 | *val = 456 41 | } 42 | 43 | // Returning pointer from a function 44 | func change2(val *int) *int { 45 | return val 46 | } 47 | -------------------------------------------------------------------------------- /14-structs/go.mod: -------------------------------------------------------------------------------- 1 | module test 2 | 3 | go 1.23.0 4 | -------------------------------------------------------------------------------- /14-structs/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "test/model" 6 | ) 7 | 8 | type Person struct { 9 | firstName string 10 | lastName string 11 | age int 12 | } 13 | 14 | type Car struct { 15 | string 16 | int 17 | } 18 | 19 | func main() { 20 | // structs 21 | user1 := Person{ 22 | lastName: "mousavi", 23 | age: 100, 24 | firstName: "mohammad", 25 | } 26 | user2 := Person{ 27 | "test", 28 | "test2", 29 | 2, 30 | } 31 | fmt.Println(user1) 32 | fmt.Println(user2) 33 | 34 | // Creating anonymous structs 35 | user3 := struct { 36 | firstName string 37 | lastName string 38 | age int 39 | }{ 40 | lastName: "mousavi", 41 | age: 1, 42 | firstName: "mohammad", 43 | } 44 | fmt.Println(user3) 45 | 46 | // Accessing individual fields of a struct 47 | user4 := Person{ 48 | lastName: "mousavi", 49 | age: 1, 50 | firstName: "mohammad", 51 | } 52 | fmt.Println(user4.firstName) 53 | 54 | // Zero value of a struct 55 | var user5 Person 56 | user5 = Person{ 57 | firstName: "aaa", 58 | lastName: "bbb", 59 | } 60 | fmt.Println(user5.firstName) 61 | fmt.Println(user5.lastName) 62 | fmt.Println(user5.age) 63 | 64 | // Anonymous fields 65 | car1 := Car{ 66 | string: "asdasd", 67 | int: 123, 68 | } 69 | fmt.Println(car1) 70 | 71 | // Exported structs and fields 72 | user6 := model.User{ 73 | LastName: "mousavi", 74 | FirstName: "mohammad", 75 | Address: model.Address{ 76 | City: "asd", 77 | }, 78 | } 79 | fmt.Println(user6.City) 80 | } 81 | -------------------------------------------------------------------------------- /14-structs/model/user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type User struct { 4 | FirstName string 5 | LastName string 6 | age int 7 | Address 8 | } 9 | 10 | type Address struct { 11 | City string 12 | code int 13 | name string 14 | } 15 | -------------------------------------------------------------------------------- /15-methods/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type User struct { 6 | name string 7 | age int 8 | Address 9 | } 10 | 11 | type Address struct { 12 | code int 13 | } 14 | 15 | // Sample Method 16 | func (a Address) printCode() { 17 | fmt.Println("code : ", a.code) 18 | } 19 | 20 | // Methods vs Functions 21 | func (u User) print() { 22 | fmt.Println("name : ", u.name) 23 | } 24 | func print(u User) { 25 | fmt.Println("name : ", u.name) 26 | } 27 | 28 | func (u User) changeName(newName string) { 29 | u.name = newName 30 | } 31 | 32 | func (u *User) changeAge(newAge int) { 33 | u.age = newAge 34 | } 35 | 36 | func main() { 37 | user := User{ 38 | name: "test", 39 | age: 30, 40 | } 41 | // Pointer Receivers vs Value Receivers 42 | fmt.Println(user) 43 | user.changeName("mohammad") 44 | fmt.Println(user) 45 | user.changeAge(35) 46 | fmt.Println(user) 47 | 48 | // Methods of anonymous struct fields 49 | user2 := User{ 50 | name: "test", 51 | age: 30, 52 | Address: Address{ 53 | code: 12, 54 | }, 55 | } 56 | user2.printCode() 57 | } 58 | -------------------------------------------------------------------------------- /16-interfaces/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Calculator interface { 6 | getSpeed() int 7 | } 8 | 9 | type car struct { 10 | name string 11 | speed int 12 | } 13 | 14 | func (c car) getSpeed() int { 15 | return c.speed 16 | } 17 | 18 | type User struct { 19 | name string 20 | speed int 21 | } 22 | 23 | func (c User) getSpeed() int { 24 | return c.speed 25 | } 26 | 27 | func Print(c Calculator) { 28 | fmt.Println(c) 29 | } 30 | 31 | // Empty interface 32 | func newPrint1(i interface{}) { 33 | fmt.Println(i) 34 | } 35 | 36 | // Type assertion 37 | func newPrint2(i interface{}) { 38 | v, ok := i.(int) 39 | fmt.Println(v, ok) 40 | } 41 | 42 | func main() { 43 | // Declaring and implementing an interface 44 | car1 := car{ 45 | name: "BMW", 46 | speed: 2000, 47 | } 48 | speed := car1.getSpeed() 49 | fmt.Println(speed) 50 | Print(car1) 51 | 52 | user1 := User{ 53 | name: "test", 54 | speed: 2000, 55 | } 56 | // Print(user1) 57 | newPrint1(car1) 58 | newPrint1(user1) 59 | 60 | a := 21 61 | newPrint2(a) 62 | b := "asd" 63 | newPrint2(b) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /17-goroutines/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func numbers() { 9 | for i := 0; i <= 5; i++ { 10 | time.Sleep(250 * time.Millisecond) 11 | fmt.Printf("%d", i) 12 | } 13 | } 14 | 15 | func alphabets() { 16 | for i := 'a'; i <= 'e'; i++ { 17 | time.Sleep(400 * time.Millisecond) 18 | fmt.Printf("%c", i) 19 | } 20 | } 21 | 22 | func main() { 23 | go numbers() 24 | go alphabets() 25 | time.Sleep(3000 * time.Millisecond) 26 | fmt.Println("main") 27 | } 28 | -------------------------------------------------------------------------------- /18-channels/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func hello(data chan bool) { 6 | fmt.Println("hello1") 7 | data <- true 8 | } 9 | 10 | func cal1(number int, ch1 chan int) { 11 | number *= 2 12 | ch1 <- number 13 | } 14 | 15 | func cal2(number int, ch2 chan int) { 16 | number += 2 17 | ch2 <- number 18 | } 19 | 20 | func sendData(data chan<- int) { 21 | data <- 10 22 | } 23 | 24 | func getNumers(data chan int) { 25 | for i := 0; i < 10; i++ { 26 | data <- i 27 | } 28 | close(data) 29 | } 30 | func main() { 31 | 32 | // Declaring channels 33 | var a chan int 34 | fmt.Println(a) 35 | 36 | b := make(chan int) 37 | fmt.Printf("%T", b) 38 | 39 | // Sending and receiving from a channel 40 | data := <-a 41 | a <- data 42 | fmt.Println(data) 43 | 44 | ch1 := make(chan bool) 45 | go hello(ch1) 46 | <-ch1 47 | fmt.Println("main2") 48 | 49 | number := 10 50 | ch2 := make(chan int) 51 | ch3 := make(chan int) 52 | go cal1(number, ch2) 53 | go cal2(number, ch3) 54 | s1, s2 := <-ch2, <-ch3 55 | fmt.Println(s1, s2) 56 | 57 | // Unidirectional channels 58 | // ch4 := make(chan<- int) 59 | ch4 := make(chan int) 60 | go sendData(ch4) 61 | f := <-ch4 62 | fmt.Println(f) 63 | 64 | // Closing channels 65 | ch5 := make(chan int) 66 | go getNumers(ch5) 67 | for v := range ch5 { 68 | fmt.Println(v) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /19-buffered-channels/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func print(i int, wg *sync.WaitGroup) { 10 | fmt.Println("start", i) 11 | time.Sleep(2 * time.Second) 12 | fmt.Println("end", i) 13 | wg.Done() 14 | } 15 | 16 | func main() { 17 | 18 | ch := make(chan int, 3) 19 | ch <- 10 20 | ch <- 100 21 | ch <- 1000 22 | 23 | fmt.Println("len", len(ch)) 24 | fmt.Println("cap", cap(ch)) 25 | fmt.Println("read ", <-ch) 26 | fmt.Println("len", len(ch)) 27 | fmt.Println("cap", cap(ch)) 28 | 29 | // WaitGroup 30 | number := 3 31 | var wg sync.WaitGroup 32 | 33 | for i := 0; i < number; i++ { 34 | wg.Add(1) 35 | go print(i, &wg) 36 | } 37 | 38 | wg.Wait() 39 | fmt.Println("finished") 40 | } 41 | -------------------------------------------------------------------------------- /20-select/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func server1(ch chan string) { 9 | ch <- "server1" 10 | } 11 | 12 | func server2(ch chan string) { 13 | ch <- "server2" 14 | } 15 | 16 | func main() { 17 | output1 := make(chan string) 18 | output2 := make(chan string) 19 | go server1(output1) 20 | go server2(output2) 21 | time.Sleep(1 * time.Second) 22 | select { 23 | case s1 := <-output1: 24 | fmt.Println(s1) 25 | case s2 := <-output2: 26 | fmt.Println(s2) 27 | } 28 | 29 | // ch := make(chan string) 30 | var ch chan string 31 | 32 | select { 33 | case s1 := <-ch: 34 | fmt.Println(s1) 35 | default: 36 | fmt.Println("no") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /21-mutex/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var x = 0 9 | 10 | func sum(wg *sync.WaitGroup, m *sync.Mutex) { 11 | m.Lock() 12 | x += 1 13 | m.Unlock() 14 | wg.Done() 15 | } 16 | 17 | func main() { 18 | var w sync.WaitGroup 19 | var m sync.Mutex 20 | for i := 0; i < 1000; i++ { 21 | w.Add(1) 22 | go sum(&w, &m) 23 | } 24 | w.Wait() 25 | fmt.Println("final: ", x) 26 | } 27 | -------------------------------------------------------------------------------- /22-defer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func print() { 6 | fmt.Println("mohammad") 7 | } 8 | func printName() { 9 | fmt.Println("mousavi") 10 | } 11 | func value(a int) { 12 | fmt.Println(a) 13 | 14 | } 15 | func main() { 16 | defer func() { fmt.Println("mohammad") }() 17 | fmt.Println("hello") 18 | 19 | a := 1 20 | defer value(a) 21 | a = 10 22 | fmt.Println(a) 23 | 24 | defer printName() 25 | fmt.Println("hello") 26 | } 27 | -------------------------------------------------------------------------------- /23-error-handling/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | f, err := os.Open("../test.txt") 11 | if err != nil { 12 | var pErr *os.PathError 13 | if errors.As(err, &pErr) { 14 | fmt.Println(pErr.Path) 15 | return 16 | } 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(f.Name()) 21 | } 22 | -------------------------------------------------------------------------------- /24-custom-errors/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | type divisionError struct { 9 | err string 10 | dividend float64 11 | divisor float64 12 | } 13 | 14 | func (e *divisionError) Error() string { 15 | return fmt.Sprintf("cannot divide %f by %f: %s", e.dividend, e.divisor, e.err) 16 | } 17 | 18 | func divide(dividend, divisor float64) (float64, error) { 19 | if divisor == 0 { 20 | return 0, &divisionError{ 21 | err: "division by zero", 22 | dividend: dividend, 23 | divisor: divisor, 24 | } 25 | } 26 | return dividend / divisor, nil 27 | } 28 | 29 | func main() { 30 | dividend := 10.0 31 | divisor := 0.0 32 | 33 | result, err := divide(dividend, divisor) 34 | if err != nil { 35 | var divErr *divisionError 36 | if errors.As(err, &divErr) { 37 | fmt.Println("error:", divErr.err) 38 | return 39 | } 40 | fmt.Println(err) 41 | return 42 | } 43 | 44 | fmt.Printf("Result of division: %0.2f\n", result) 45 | } 46 | -------------------------------------------------------------------------------- /25-files/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | // read-files 10 | contents, err := os.ReadFile("test.txt") 11 | if err != nil { 12 | fmt.Println("File reading error", err) 13 | return 14 | } 15 | for _, v := range contents { 16 | fmt.Printf("%c \n", v) 17 | } 18 | 19 | // write-files 20 | f, err := os.Create("test.txt") 21 | if err != nil { 22 | fmt.Println(err) 23 | return 24 | } 25 | l, err := f.WriteString("mohammad") 26 | if err != nil { 27 | fmt.Println(err) 28 | f.Close() 29 | return 30 | } 31 | fmt.Println(l) 32 | err = f.Close() 33 | if err != nil { 34 | fmt.Println(err) 35 | return 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /25-files/test.txt: -------------------------------------------------------------------------------- 1 | mohammad -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn Go (Golang) 🚀 2 | 3 | This repository contains a series of tutorials on the Go (Golang) programming language, which are also available on our YouTube channel. The goal of this project is to provide step-by-step learning resources to help you master this popular and versatile language. 4 | 5 | ## 📺 Video Tutorials 6 | 7 | All tutorials are available on our YouTube channel. Check out the videos through the link below: 8 | 9 | [YouTube Channel](https://www.youtube.com/@topdemy/playlists) 10 | 11 | ## 📂 Repository Structure 12 | 13 | The repository is divided into different sections, each focusing on a specific topic in Go: 14 | 15 | - `01-Basics`: Fundamentals and introductory concepts of Go 16 | - `02-Advanced`: Advanced topics including Concurrency, Goroutines, and Channels 17 | - `03-Projects`: Small projects to practice and implement learned concepts 18 | - `...` (additional sections as needed) 19 | 20 | ## 🛠️ Prerequisites 21 | 22 | To run the code and exercises in this repository, you need to have Go installed. You can download and install Go from the link below: 23 | 24 | - [Download and Install Go](https://golang.org/dl/) 25 | 26 | ## 🚀 How to Use 27 | 28 | 1. Clone the repository: 29 | 30 | ```bash 31 | git clone https://github.com/mousav1/learn-go.git 32 | ``` 33 | 34 | 1. Navigate to the repository folder: 35 | 36 | ```bash 37 | cd learn-go 38 | ``` 39 | 40 | 41 | 1. Each folder contains code related to a specific topic; to run any code, navigate to the respective folder and execute: 42 | 43 | ```bash 44 | cgo run main.go 45 | 46 | ``` 47 | 48 | ## 🤝 Contribution 49 | 50 | We welcome contributions! If you have suggestions for improving the content or would like to help enhance the code, feel free to submit a Pull Request or create an Issue. 51 | 52 | 53 | ## 📧 Contact Us 54 | 55 | Visit our website: 56 | 57 | - [Topdemy](https://topdemy.ir) 58 | You can also follow us on social media: 59 | 60 | - [YouTube](https://www.youtube.com/@topdemy/playlists) 61 | --------------------------------------------------------------------------------