├── .gitignore ├── 02-Introduction ├── 03-ProjectStructure │ ├── getInputExample.go │ ├── helloWorldInFunc.go │ └── main.go ├── 06-ModuleTest │ ├── Banking │ │ ├── card.go │ │ └── sheba.go │ ├── PersianDate │ │ └── dateConversions.go │ └── go.mod ├── 07-HelloWorld │ └── main.go └── Readme.md ├── 03-DataTypes ├── 02-BasicDataTypes │ └── integer.go ├── 05-Enums │ └── enum.go ├── 06-Pointer │ ├── example0.go │ ├── example1.go │ └── pointer2pointer.go └── 07-Rune │ └── example.go ├── 04-Variables ├── 01-Declaration │ └── declaration.go ├── 02-Constants │ └── consts.go ├── 03-Scope │ └── scope.go └── 04-Functions │ ├── funcs.go │ └── print.go ├── 05-ConditionalStatements ├── 01-IfElse │ └── ifelse.go ├── 02-Switch │ ├── switch.go │ ├── switch2.go │ └── switch3.go └── 03-Switch │ ├── break.go │ ├── fallThrough-bad.go │ └── fallThrough-good.go ├── 06-Loops └── 01-For │ ├── breakContinue.go │ ├── example.go │ └── fors.go ├── 07-CompositeDataTypes ├── 01-Array │ ├── array.go │ ├── copy.go │ └── search.go ├── 02-Slice │ ├── SliceInitBenchmark │ │ ├── benchmark_test.go │ │ └── go.mod │ ├── append.go │ ├── copy.go │ ├── example1.go │ ├── func.go │ ├── leetCode-twoSum.go │ ├── loop.go │ ├── other.go │ └── two_sum_bench │ │ ├── go.mod │ │ ├── two_sum.go │ │ └── two_sum_test.go └── 03-Map │ ├── creation.go │ ├── crud.go │ └── other.go ├── 08-Function ├── 01-intro │ └── intro.go ├── 02-MultipleReturns │ └── example.go ├── 03-NamedReturnValue │ └── example.go ├── 04-Variadic │ ├── example.go │ ├── example1.go │ └── example2.go ├── 05-Anonymous │ ├── example1.go │ └── example2.go ├── 06-Clouser │ └── example.go ├── 07-Defer │ ├── destination.txt │ ├── example.go │ └── source.txt └── Project │ └── Hotel.go ├── 09-Structs ├── 03-Instantiation │ └── example.go ├── 04-Methods │ ├── HotelProjectWithMethod.go │ └── example.go ├── 05-Abstraction │ ├── badExample.go │ └── example.go ├── 06-Polymorphism │ ├── example.go │ └── ticketing.go ├── 07-Encapsulation │ └── example.go ├── 08-EmbededStructs │ ├── CsharpInheritance │ │ ├── BadExample.cs │ │ ├── CsharpInheritance.csproj │ │ ├── CsharpInheritance.sln │ │ ├── GoodExample.cs │ │ └── Program.cs │ ├── main.go │ └── main_test.go ├── 09-Composition │ └── example.go ├── 10-FunctionalOptionsPattern │ ├── builder.go │ └── exampleWithFOP.go ├── 11-StructTags │ └── example.go └── 12-AnonymousStructs │ └── example.go ├── 10-Interfaces ├── 02-Diffs │ ├── Example.cs │ ├── example.go │ └── example.ts ├── 03-Interface │ └── example.go ├── 04-EmbeddedInterfaces │ └── example.go ├── 05-EmptyInterfaces │ └── example.go └── 06-MiniProject │ ├── 01-Notification │ ├── entities │ │ ├── notificationType.go │ │ └── order.go │ ├── externalServices │ │ ├── emailService.go │ │ ├── nilNotifyService.go │ │ ├── notifier.go │ │ └── smsService.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── services │ │ └── orderService.go │ ├── 01-Notifier │ ├── .vscode │ │ └── launch.json │ ├── consts │ │ └── notificationType.go │ ├── entities │ │ └── user.go │ ├── go.mod │ ├── main.go │ ├── notification.exe │ └── services │ │ └── notifier.go │ ├── project.go │ └── project1.go ├── 11-Modules ├── 01-Module │ ├── go.mod │ ├── go.sum │ ├── local │ │ └── go-jalaali │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── convertion.go │ │ │ ├── errors.go │ │ │ ├── format.go │ │ │ ├── go.mod │ │ │ ├── jalaali.go │ │ │ ├── jalaali_test.go │ │ │ └── utils.go │ └── main.go ├── 02-Workspace │ ├── go.mod │ ├── go.sum │ ├── go.work │ ├── local │ │ └── go-jalaali │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── convertion.go │ │ │ ├── go.mod │ │ │ ├── jalaali.go │ │ │ ├── jalaali_test.go │ │ │ └── utils.go │ └── main.go ├── 03-ModuleExample │ ├── go.mod │ ├── go.sum │ ├── local │ │ └── go-jalaali │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── convertion.go │ │ │ ├── errors.go │ │ │ ├── format.go │ │ │ ├── go.mod │ │ │ ├── jalaali.go │ │ │ ├── jalaali_test.go │ │ │ └── utils.go │ ├── main.go │ └── services │ │ ├── test2Service.go │ │ └── testService.go └── 03-WorkspaceExample │ ├── go.mod │ ├── go.sum │ ├── go.work │ ├── local │ └── go-jalaali │ │ ├── LICENSE │ │ ├── README.md │ │ ├── convertion.go │ │ ├── errors.go │ │ ├── format.go │ │ ├── go.mod │ │ ├── jalaali.go │ │ ├── jalaali_test.go │ │ └── utils.go │ ├── main.go │ └── services │ ├── test2Service.go │ └── testService.go ├── 12-Generics ├── 02-Examples │ ├── example1.go │ └── example2.go └── 03-MiniProject │ ├── 01-List │ ├── generics │ │ └── list.go │ ├── go.mod │ ├── go.sum │ └── main.go │ └── 02-List │ ├── .vscode │ └── launch.json │ ├── go.mod │ ├── go.sum │ └── project.go ├── 13-Errors ├── 02-Error │ ├── 17162-7Learn │ │ ├── .vscode │ │ │ └── launch.json │ │ ├── go.mod │ │ └── main.go │ ├── createError.go │ ├── customError.go │ └── error1.go ├── 03-Wrapping │ ├── dest.txt │ ├── method1.go │ ├── method2.go │ └── src1.txt └── Panic │ ├── example1.go │ └── test1.go ├── 14-Logging ├── 02-LogLibrary │ ├── example1.go │ └── log.txt ├── 03-LogToFile │ ├── core │ │ └── logger.go │ ├── go.mod │ ├── go.sum │ ├── log.txt │ └── main.go ├── 03-LoggingWithThirdParty │ ├── go.mod │ ├── go.sum │ └── main.go └── 04-MiniProject │ ├── core │ └── logger.go │ ├── entities │ ├── notificationType.go │ └── order.go │ ├── externalServices │ ├── emailService.go │ ├── nilNotifyService.go │ ├── notifier.go │ └── smsService.go │ ├── go.mod │ ├── go.sum │ ├── log.txt │ ├── main.go │ └── services │ └── orderService.go ├── 15-Concurrency ├── 03-Intro │ ├── go.mod │ └── main.go ├── 04-WaitGroups │ ├── go.mod │ └── main.go ├── 05-Mutex │ ├── 01-MutexExample │ │ ├── go.mod │ │ ├── main.go │ │ ├── mutex.go │ │ └── simple.go │ └── main.go ├── 06-Cond │ ├── example1.go │ ├── go.mod │ └── main.go ├── 07-Once │ ├── bad.go │ ├── go.mod │ ├── good.go │ └── main.go ├── 08-Pool │ ├── 01-ConnectionPool │ │ ├── go.mod │ │ ├── main.go │ │ └── main_test.go │ └── 02-Examples │ │ ├── go.mod │ │ ├── main.go │ │ ├── memoryStatus.go │ │ ├── poolExample.go │ │ └── poolExample_test.go ├── 09-Channels │ ├── .vscode │ │ └── launch.json │ ├── examples │ │ ├── http.go │ │ ├── httpu.go │ │ └── intro.go │ ├── go.mod │ └── main.go ├── 10-(Un)bufferedChannels │ ├── examples │ │ ├── bufferedExamples.go │ │ ├── intro.go │ │ ├── select.go │ │ └── unbufferedExamples.go │ ├── go.mod │ └── main.go └── 12-Select │ ├── examples │ └── livescore.go │ ├── go.mod │ └── main.go ├── 16-Json ├── examples │ ├── marshal.go │ ├── unMarshal.go │ └── unMarshalFromApi.go ├── go.mod └── main.go ├── 17-Http ├── 02-Server │ ├── examples │ │ ├── servemux.go │ │ └── server.go │ ├── go.mod │ └── main.go ├── 04-RequestManagement │ ├── go.mod │ ├── handler │ │ └── users.go │ ├── main.go │ ├── management │ │ └── server.go │ └── models │ │ └── user.go ├── 05-ResponseManagement │ ├── api │ │ └── result.go │ ├── go.mod │ ├── handler │ │ └── users.go │ ├── main.go │ ├── management │ │ └── server.go │ └── models │ │ └── user.go ├── 06-Context │ ├── api │ │ └── result.go │ ├── examples │ │ ├── internal_cancel.go │ │ └── send_value.go │ ├── go.mod │ ├── main.go │ └── management │ │ └── server.go └── 07-MiniProject │ ├── .vscode │ └── launch.json │ ├── Dockerfile │ ├── database │ └── db.go │ ├── go.mod │ ├── handlers │ └── movie.go │ ├── main.go │ ├── management │ └── server.go │ ├── models │ └── movie.go │ └── utils │ ├── api_error.go │ └── api_result.go ├── 20-Docker └── docker-compose.yml └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | **/bin/* 2 | **/obj/* -------------------------------------------------------------------------------- /02-Introduction/03-ProjectStructure/getInputExample.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | names() 10 | } 11 | 12 | func names() { 13 | fmt.Println("Enter your name:") 14 | 15 | var name string 16 | fmt.Scanln(&name) 17 | // Check whether name has a vowel 18 | for _, v := range strings.ToLower(name) { 19 | if v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u' { 20 | fmt.Println("Your name contains a vowel.") 21 | return 22 | } 23 | } 24 | fmt.Println("Your name does not contain a vowel.") 25 | } 26 | -------------------------------------------------------------------------------- /02-Introduction/03-ProjectStructure/helloWorldInFunc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | hello() 7 | } 8 | 9 | func hello() { 10 | fmt.Println("Hello, World!") 11 | } 12 | -------------------------------------------------------------------------------- /02-Introduction/03-ProjectStructure/main.go: -------------------------------------------------------------------------------- 1 | // Declaration of the main package 2 | package main 3 | 4 | // Importing packages 5 | import ( 6 | "fmt" 7 | "sort" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | // Main function 13 | func main() { 14 | 15 | // Sorting the given slice 16 | s := []int{345, 78, 123, 10, 76, 2, 567, 5} 17 | sort.Ints(s) 18 | fmt.Println("Sorted slice: ", s) 19 | 20 | // Finding the index 21 | fmt.Println("Index value: ", strings.Index("GeeksforGeeks", "ks")) 22 | 23 | // Finding the time 24 | fmt.Println("Time: ", time.Now().Unix()) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /02-Introduction/06-ModuleTest/Banking/card.go: -------------------------------------------------------------------------------- 1 | package banking 2 | 3 | func GetbankName(cardNumber string) string { 4 | return "" 5 | } 6 | -------------------------------------------------------------------------------- /02-Introduction/06-ModuleTest/Banking/sheba.go: -------------------------------------------------------------------------------- 1 | package banking 2 | 3 | 4 | func GetshebaNumber(cardNumber string) string { 5 | return "" 6 | } -------------------------------------------------------------------------------- /02-Introduction/06-ModuleTest/PersianDate/dateConversions.go: -------------------------------------------------------------------------------- 1 | package persiandate 2 | 3 | func miladiToShamsi() { 4 | 5 | } 6 | 7 | func shamsiToMiladi() { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /02-Introduction/06-ModuleTest/go.mod: -------------------------------------------------------------------------------- 1 | module PersianUtil 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /02-Introduction/07-HelloWorld/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | fmt.Println("Hello World!") 8 | } 9 | -------------------------------------------------------------------------------- /02-Introduction/Readme.md: -------------------------------------------------------------------------------- 1 | # Golang-Tutorial 2 | 3 | ## Session 2 4 | 5 | **Tools**: 6 | 7 | ### Install Go Language 1.18 8 | 9 | #### Windows: 10 | 11 | [Download here](https://go.dev/dl/go1.18.1.windows-amd64.msi) and then install 12 | 13 | #### Linux Method 1: 14 | 15 | Run this commands in terminal: 16 | 17 | sudo apt update 18 | sudo apt search golang-go 19 | sudo apt search gccgo-go 20 | sudo apt install golang-go 21 | 22 | #### Linux Method 2: 23 | 24 | 1. [Download file](https://go.dev/dl/go1.18.1.linux-amd64.tar.gz) 25 | 2. Extract file `tar -xf "go1.18.1.linux-amd64.tar.gz"` 26 | 3. Setup permissions `sudo chown -R root:root ./go` 27 | 4. Move go binaries to local folder `sudo mv -v go /usr/local` 28 | 5. for Setup go path, open profile: `code ~/.bash_profile` or `code ~/.profile` 29 | 6. Append following to lines to file: 30 | ``` 31 | export GOPATH=$HOME/go 32 | export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin 33 | ``` 34 | 7. source this file: `source ~/.bash_profile` or `source ~/.profile` 35 | 8. Run `go version` to check if go is installed 36 | 37 | ### Install Go Debugger 38 | 39 | Run this command: ` go install github.com/go-delve/delve/cmd/dlv` 40 | 41 | ### Install Visual Studio Code 42 | 43 | [Download here](https://code.visualstudio.com/download) 44 | 45 | ### Install Git 46 | 47 | #### Windows: 48 | 49 | [Download frome here](https://gitforwindows.org/) and then install 50 | 51 | #### Linux: 52 | 53 | Run this commands in terminal or see this [link](https://git-scm.com/download/linux): 54 | 55 | sudo apt update 56 | sudo apt-get install git 57 | 58 | ### VS Code Extensions 59 | 60 | Run this commands in terminal 61 | 62 | ``` 63 | code --install-extension aaron-bond.better-comments 64 | code --install-extension christian-kohler.path-intellisense 65 | code --install-extension ckolkman.vscode-postgres 66 | code --install-extension cweijan.vscode-redis-client 67 | code --install-extension donjayamanne.githistory 68 | code --install-extension eamodio.gitlens 69 | code --install-extension esbenp.prettier-vscode 70 | code --install-extension formulahendry.code-runner 71 | code --install-extension golang.go 72 | code --install-extension HookyQR.beautify 73 | code --install-extension IBM.output-colorizer 74 | code --install-extension mhutchie.git-graph 75 | code --install-extension ms-azuretools.vscode-docker 76 | code --install-extension PKief.material-icon-theme 77 | code --install-extension premparihar.gotestexplorer 78 | code --install-extension rangav.vscode-thunder-client 79 | code --install-extension redhat.vscode-yaml 80 | code --install-extension streetsidesoftware.code-spell-checker 81 | code --install-extension TabNine.tabnine-vscode 82 | code --install-extension VisualStudioExptTeam.vscodeintellicode 83 | code --install-extension vscode-icons-team.vscode-icons 84 | code --install-extension wmaurer.change-case 85 | ``` 86 | -------------------------------------------------------------------------------- /03-DataTypes/02-BasicDataTypes/integer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/bits" 6 | "unsafe" 7 | ) 8 | 9 | func main() { 10 | 11 | var num int = 100000000000000000 12 | var num8 int8 = 100 13 | var num16 int16 = 10000 14 | var num32 int32 = 10000000 15 | var num64 int64 = 100000000000000000 16 | 17 | fmt.Printf("num %d bytes \n", unsafe.Sizeof(num)) 18 | fmt.Printf("num8 %d bytes \n", unsafe.Sizeof(num8)) 19 | fmt.Printf("num16 %d bytes \n", unsafe.Sizeof(num16)) 20 | fmt.Printf("num32 %d bytes \n", unsafe.Sizeof(num32)) 21 | fmt.Printf("num64 %d bytes \n", unsafe.Sizeof(num64)) 22 | 23 | var a = bits.UintSize 24 | 25 | fmt.Println(a) 26 | 27 | var fnum float32 = 10.2 // 3.4 * 10^ -38 28 | var fnum8 float64 // 1.7 * 10 ^ -308 29 | 30 | fmt.Printf("fnum %d bytes \n", unsafe.Sizeof(fnum)) 31 | fmt.Printf("fnum8 %d bytes \n", unsafe.Sizeof(fnum8)) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /03-DataTypes/05-Enums/enum.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | const apiUrl = "https://api.github.com/users/" 9 | 10 | type Order struct { 11 | Id int 12 | Price int 13 | Status OrderStatus 14 | } 15 | 16 | type OrderStatus int 17 | 18 | const ( 19 | Created OrderStatus = 0 20 | Processing = 1 21 | WaitForPayment = 2 22 | PaymentDone = 3 23 | Issue = 4 24 | Refund = 5 25 | ) 26 | 27 | func main() { 28 | 29 | order1 := Order{Id: 1, Price: 100, Status: Created} 30 | order2 := Order{Id: 2, Price: 300, Status: PaymentDone} 31 | order3 := Order{Id: 3, Price: 200, Status: Issue} 32 | 33 | order1Json, _ := json.Marshal(order1) 34 | order2Json, _ := json.Marshal(order2) 35 | order3Json, _ := json.Marshal(order3) 36 | println(string(order1Json)) 37 | println(string(order2Json)) 38 | println(string(order3Json)) 39 | fmt.Printf("%+v", order3) 40 | } 41 | -------------------------------------------------------------------------------- /03-DataTypes/06-Pointer/example0.go: -------------------------------------------------------------------------------- 1 | // You can edit this code! 2 | // Click here and start typing. 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | i, j := 20, 40 9 | 10 | var ip *int = &i 11 | var jp *int = &j 12 | 13 | fmt.Println("Address of i:", &i) 14 | fmt.Println("Address of ip pointer:", ip) 15 | 16 | fmt.Println("Address of j:", &j) 17 | fmt.Println("Address of jp pointer:", jp) 18 | 19 | i2 := i 20 | i2 = i2 + 2 21 | fmt.Println("value of i after increase i2", i) 22 | fmt.Println("value of i2 after increase i2", i2) 23 | 24 | fmt.Println("Address of i2:", &i2) 25 | 26 | var ip2 *int = &i 27 | 28 | *ip2 = *ip2 + 2 29 | fmt.Println("value of ip2", *ip2) 30 | fmt.Println("value of i", i) 31 | } 32 | -------------------------------------------------------------------------------- /03-DataTypes/06-Pointer/example1.go: -------------------------------------------------------------------------------- 1 | // You can edit this code! 2 | // Click here and start typing. 3 | package main 4 | 5 | func main() { 6 | num := 20 7 | println("Address of num:", &num) 8 | changeNumberByValue(num) 9 | println("value of num:", num) 10 | 11 | changeNumberByRef(&num) 12 | println("value of num:", num) 13 | 14 | } 15 | func changeNumberByRef(num *int) { 16 | println("changeNumberByRef Address of num:", num) 17 | *num = *num + 2 18 | } 19 | 20 | func changeNumberByValue(num int) { 21 | println("changeNumberByValue Address of num:", &num) 22 | num = num + 2 23 | } 24 | -------------------------------------------------------------------------------- /03-DataTypes/06-Pointer/pointer2pointer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | name := "hamed" 5 | namePtr := &name 6 | namePtr2Ptr := &namePtr 7 | 8 | } 9 | 10 | func search1() { 11 | t1 := &Tree[int]{ 12 | cmp: func(a int, b int) int { 13 | if a < b { 14 | return -1 15 | } else if a > b { 16 | return 1 17 | } else { 18 | return 0 19 | } 20 | 21 | }, 22 | root: &leaf[int]{val: 12}, 23 | } 24 | 25 | for i := 0; i < 1000; i++ { 26 | root := t1.root 27 | var left = root.left 28 | var right = root.right 29 | left.val = i 30 | } 31 | } 32 | 33 | func search2() { 34 | 35 | } 36 | 37 | func (bt *Tree[T]) find1(val T) *leaf[T] { 38 | pl := bt.root 39 | for pl != nil { 40 | switch cmp := bt.cmp(val, (*pl).val); { 41 | case cmp < 0: 42 | pl = (*pl).left 43 | case cmp > 0: 44 | pl = (*pl).right 45 | default: 46 | return pl 47 | } 48 | } 49 | return pl 50 | } 51 | 52 | func (bt *Tree[T]) find(val T) **leaf[T] { 53 | pl := &bt.root 54 | for *pl != nil { 55 | switch cmp := bt.cmp(val, (*pl).val); { 56 | case cmp < 0: 57 | pl = &(*pl).left 58 | case cmp > 0: 59 | pl = &(*pl).right 60 | default: 61 | return pl 62 | } 63 | } 64 | return pl 65 | } 66 | 67 | type Tree[T any] struct { 68 | cmp func(T, T) int 69 | root *leaf[T] 70 | } 71 | 72 | type leaf[T any] struct { 73 | val T 74 | left, right *leaf[T] 75 | } 76 | -------------------------------------------------------------------------------- /03-DataTypes/07-Rune/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | char1 := '😀' 10 | 11 | char2 := '😄' 12 | char3 := 128525 13 | 14 | fmt.Printf("char1: %d %T\n", char1, char1) 15 | 16 | fmt.Printf("char1: %d %T\n", char2, char2) 17 | fmt.Printf("char1: %c %T\n", char3, char3) 18 | 19 | myStr := "Hello World 😀 😄" 20 | 21 | fmt.Printf("myStr: %s %T, len: %d, size: %d \n ", myStr, myStr, len(myStr), unsafe.Sizeof(myStr)) 22 | 23 | for i := 0; i < len(myStr); i++ { 24 | fmt.Printf("myStr[%d]: %c %T\n", i, myStr[i], myStr[i]) 25 | } 26 | 27 | myRune := []rune("Hello World 😀 😄") 28 | 29 | fmt.Printf("myRune: %v %T, len: %d, size: %d \n ", myRune, myRune, len(myRune), unsafe.Sizeof(myRune)) 30 | 31 | for i := 0; i < len(myRune); i++ { 32 | fmt.Printf("myStr[%d]: %c %T\n", i, myRune[i], myRune[i]) 33 | } 34 | 35 | myRune = []rune("سلام دنیا") 36 | myStr = "سلام دنیا" 37 | 38 | fmt.Printf("myStr: %s %T, len: %d, size: %d \n ", myStr, myStr, len(myStr), unsafe.Sizeof(myStr)) 39 | 40 | for i := 0; i < len(myStr); i++ { 41 | fmt.Printf("myStr[%d]: %c %T\n", i, myStr[i], myStr[i]) 42 | } 43 | 44 | fmt.Printf("myRune: %v %T, len: %d, size: %d \n ", myRune, myRune, len(myRune), unsafe.Sizeof(myRune)) 45 | 46 | for i := 0; i < len(myRune); i++ { 47 | fmt.Printf("myStr[%d]: %c %T\n", i, myRune[i], myRune[i]) 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /04-Variables/01-Declaration/declaration.go: -------------------------------------------------------------------------------- 1 | // You can edit this code! 2 | // Click here and start typing. 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "runtime/debug" 8 | ) 9 | 10 | func main() { 11 | //var varName type = value 12 | // 1 13 | var number int = 12 14 | var firstName string = "Ali" 15 | 16 | println("number: ", number) 17 | println("firstName: ", firstName) 18 | 19 | // 2 20 | var i2 int 21 | var s2 string 22 | 23 | println("i2: ", i2) 24 | println("s2: ", s2) 25 | 26 | // 3 27 | var i3 = 3 28 | var f1 = 3.44 29 | var s3 = "Iran" 30 | 31 | println("i3: ", i3) 32 | println("f1: ", f1) 33 | println("s3: ", s3) 34 | 35 | // 4 36 | i4 := 44 37 | f2 := 55.2 38 | city := "Tehran" 39 | 40 | println("i4: ", i4) 41 | println("f2: ", f2) 42 | println("city: ", city) 43 | 44 | // 5 45 | var i5, f3, s5 = 55, 65.2, "Mazandaran" 46 | i6, f4, s6 := 55, 65.2, "Mazandaran" 47 | 48 | println("i5: ", i5) 49 | println("f3: ", f3) 50 | println("s5: ", s5) 51 | 52 | println("i6: ", i6) 53 | println("f4: ", f4) 54 | println("s6: ", s6) 55 | 56 | // 6 57 | 58 | var ( 59 | i7 = 12 60 | f5 = 22.5 61 | s7 = "Isfahan" 62 | ) 63 | 64 | println("i7: ", i7) 65 | println("f5: ", f5) 66 | println("s7: ", s7) 67 | fmt.Printf("Stack is 1 %s\n\n\n", string(debug.Stack())) 68 | fmt.Printf("Stack is 2 %s\n\n\n", string(debug.Stack())) 69 | debug.PrintStack() 70 | println("i7: ", i7) 71 | debug.PrintStack() 72 | 73 | } 74 | -------------------------------------------------------------------------------- /04-Variables/02-Constants/consts.go: -------------------------------------------------------------------------------- 1 | // You can edit this code! 2 | // Click here and start typing. 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | const pi float64 = 3.14 9 | const ( 10 | name = "iran" 11 | number = 25 12 | city = "ahwaz" 13 | ) 14 | 15 | fmt.Printf("%f \n", pi) 16 | 17 | fmt.Printf("name: %s number: %d city: %s pi: %f \n", name, number, city, pi) 18 | 19 | const googleBaseUrl = "https://www.google.com" 20 | const googleMapUrl = "/maps" 21 | 22 | println(googleBaseUrl, googleMapUrl) 23 | } 24 | -------------------------------------------------------------------------------- /04-Variables/03-Scope/scope.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | var globalBlock = 125 // globalBlock is a global variable 4 | 5 | func main() { 6 | 7 | println(globalBlock) 8 | { 9 | var localBlock = 124 // localBlock is a local variable 10 | println(localBlock) 11 | 12 | { 13 | var localBlock = 1250 // this is a local variable 14 | localBlock = localBlock * 9 15 | println(localBlock) 16 | } 17 | println(localBlock) 18 | } 19 | println(globalBlock) 20 | //println(localBlock) 21 | 22 | { 23 | // var block2 = 123 24 | } 25 | } 26 | 27 | func calc() { 28 | globalBlock = globalBlock + 10 29 | } 30 | -------------------------------------------------------------------------------- /04-Variables/04-Functions/funcs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | myString := "this is golang tutorial go go" 10 | 11 | fmt.Println("EqualFold", strings.Contains(myString, "go1")) 12 | fmt.Println("EqualFold", strings.ContainsAny(myString, "go1")) 13 | fmt.Println("EqualFold", strings.Count(myString, "go")) 14 | fmt.Println(strings.Cut(myString, "go1")) 15 | 16 | myStringArray := strings.Split(myString, " ") 17 | 18 | println("Word Count: ", len(myStringArray)) 19 | 20 | for _, item := range myStringArray { 21 | println(item) 22 | } 23 | 24 | myStringArray2 := strings.Join(myStringArray, ",") 25 | 26 | println("Join", myStringArray2) 27 | 28 | println("Repeat", strings.Repeat("iran ", 10)) 29 | 30 | println("Replace", strings.Replace(myString, "golang", "go", 3)) 31 | println("ReplaceAll", strings.ReplaceAll(myString, "go", "golang")) 32 | 33 | println("Compare", strings.Compare("golang", "golang")) 34 | println("Compare", strings.Compare("Golang", "golang")) 35 | println("Compare", strings.Compare("Golang", "GOLANG")) 36 | 37 | println("EqualFold", strings.EqualFold("Golang", "GOLANG")) 38 | println("EqualFold", strings.EqualFold("Golang", "golang")) 39 | 40 | 41 | println("HasPrefix", strings.HasPrefix("Iran", "Ir")) 42 | println("HasPrefix", strings.HasPrefix("Iran", "IR")) 43 | 44 | println("HasSuffix", strings.HasSuffix("Iran", "an")) 45 | println("HasSuffix", strings.HasSuffix("Iran", "n")) 46 | 47 | println("Index an", strings.Index("Iran", "an")) 48 | println("Index r", strings.Index("Iran", "r")) 49 | 50 | 51 | println("ToLower", strings.ToLower("IrAn")) 52 | println("ToUpper", strings.ToUpper("IrAn")) 53 | println("Title", strings.Title("Iran is a country")) 54 | 55 | println("Trim", strings.Trim(" Iran is a country ", " ")) 56 | println("TrimLeft", strings.TrimLeft("!!Iran is a country!!", "!")) 57 | println("TrimRight", strings.TrimRight("!!Iran is a country!!", "!")) 58 | println("Trim", strings.Trim("!!Iran is a country!!", "!")) 59 | 60 | 61 | 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /04-Variables/04-Functions/print.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | name := "Mahtab" 8 | age := 28 9 | nationalCode := 4832145478 10 | score := 7.5 11 | print("My name is ", name, " and my age is ", age, " and my national code is ", nationalCode, " and my score is ", score, "\n") 12 | println("My name is", name, "and my age is", age, "and my national code is", nationalCode, "and my score is", score) 13 | // println() 14 | fmt.Printf("My name is %s and my age is %d and my national code is %d and my score is %f\n", name, age, nationalCode, score) 15 | 16 | fmt.Printf("name: My type is %T\n", name) 17 | fmt.Printf("nationalCode binary is %b", nationalCode) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /05-ConditionalStatements/01-IfElse/ifelse.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var salary float64 8 | var minSalary float64 = 5_600_000 9 | var taxPercent float64 = 0 10 | var knowledgeBase bool = true 11 | 12 | fmt.Print("Enter your salary: ") 13 | fmt.Scanln(&salary) 14 | 15 | if salary <= minSalary { 16 | taxPercent = 0 17 | } else if knowledgeBase || salary > minSalary && salary <= minSalary*2 { 18 | taxPercent = 0.05 19 | } else if salary > minSalary*2 && salary <= minSalary*3 { 20 | taxPercent = 0.07 21 | } else if salary > minSalary*3 && salary <= minSalary*4 { 22 | taxPercent = 0.10 23 | } else { 24 | taxPercent = 0.15 25 | } 26 | 27 | fmt.Printf("Your tax percent is: %.2f\n", taxPercent) 28 | fmt.Printf("Your tax is: %.2f\n", taxPercent*salary) 29 | 30 | fmt.Printf("Your salary is: %.2f\n", salary-taxPercent*salary) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /05-ConditionalStatements/02-Switch/switch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var score float64 7 | 8 | println("Enter your score: ") 9 | fmt.Scanln(&score) 10 | 11 | switch { 12 | case score >= 16 && score <= 20: 13 | println("A") 14 | case score >= 11 && score <= 15.99: 15 | println("B") 16 | case score >= 6 && score <= 10.99: 17 | println("C") 18 | case score >= 0 && score <= 5.99: 19 | println("D") 20 | default: 21 | println("Unknown") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /05-ConditionalStatements/02-Switch/switch2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var num int 8 | var provinceName string 9 | 10 | println("Please enter num: ") 11 | 12 | fmt.Scanln(&num) 13 | 14 | switch num { 15 | case 72, 82, 92: 16 | provinceName = "Mazandaran" 17 | case 11, 22, 33, 44, 55, 66, 77, 88, 99, 10, 20, 30, 40, 50, 60, 70, 80, 90: 18 | provinceName = "Tehran" 19 | case 13, 23, 43, 53: 20 | provinceName = "Isfahan" 21 | case 47, 57, 67: 22 | provinceName = "Markazi" 23 | default: 24 | provinceName = "Unknown" 25 | } 26 | 27 | println(provinceName) 28 | } 29 | -------------------------------------------------------------------------------- /05-ConditionalStatements/02-Switch/switch3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var salary float64 8 | var minSalary float64 = 5_600_000 9 | var taxPercent float64 = 0 10 | 11 | fmt.Print("Enter your salary: ") 12 | fmt.Scanln(&salary) 13 | 14 | switch { 15 | case salary <= minSalary: 16 | taxPercent = 0 17 | case salary > minSalary && salary <= minSalary*2: 18 | taxPercent = 0.05 19 | case salary > minSalary*2 && salary <= minSalary*3: 20 | taxPercent = 0.07 21 | case salary > minSalary*3 && salary <= minSalary*4: 22 | taxPercent = 0.10 23 | default: 24 | taxPercent = 0.15 25 | } 26 | 27 | fmt.Printf("Your tax percent is: %.2f\n", taxPercent) 28 | fmt.Printf("Your tax is: %.2f\n", taxPercent*salary) 29 | 30 | fmt.Printf("Your salary is: %.2f\n", salary-taxPercent*salary) 31 | 32 | } 33 | -------------------------------------------------------------------------------- /05-ConditionalStatements/03-Switch/break.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var score float64 9 | 10 | println("Enter your score: ") 11 | fmt.Scanln(&score) 12 | 13 | switch { 14 | case score >= 16 && score <= 20: 15 | println("A") 16 | break 17 | case score >= 11 && score <= 15.99: 18 | println("B") 19 | case score >= 6 && score <= 10.99: 20 | println("C") 21 | case score >= 0 && score <= 5.99: 22 | println("D") 23 | default: 24 | println("Unknown") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /05-ConditionalStatements/03-Switch/fallThrough-bad.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | 10 | var notificationType string // "sms,email,push" 11 | 12 | println("Enter notification type: ") 13 | 14 | fmt.Scanln(¬ificationType) 15 | 16 | switch { 17 | case strings.Contains(notificationType, "sms"): 18 | println("SMS sent") 19 | fallthrough 20 | case strings.Contains(notificationType, "email"): 21 | println("Email sent") 22 | fallthrough 23 | case strings.Contains(notificationType, "push"): 24 | println("Push sent") 25 | default: 26 | println("Unknown") 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /05-ConditionalStatements/03-Switch/fallThrough-good.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const monthDays1 int = 31 6 | const monthDays2 int = 30 7 | const monthDays3 int = 29 8 | 9 | func main() { 10 | 11 | var month int 12 | var totalDays int = 0 13 | 14 | println("Please enter a month number: ") 15 | 16 | fmt.Scanln(&month) 17 | 18 | switch month { 19 | case 12: 20 | totalDays += monthDays3 21 | fallthrough 22 | case 11: 23 | totalDays += monthDays2 24 | fallthrough 25 | case 10: 26 | totalDays += monthDays2 27 | fallthrough 28 | case 9: 29 | totalDays += monthDays2 30 | fallthrough 31 | case 8: 32 | totalDays += monthDays2 33 | fallthrough 34 | case 7: 35 | totalDays += monthDays2 36 | fallthrough 37 | case 6: 38 | totalDays += monthDays1 39 | fallthrough 40 | case 5: 41 | totalDays += monthDays1 42 | fallthrough 43 | case 4: 44 | totalDays += monthDays1 45 | fallthrough 46 | case 3: 47 | totalDays += monthDays1 48 | fallthrough 49 | case 2: 50 | totalDays += monthDays1 51 | fallthrough 52 | case 1: 53 | totalDays += monthDays1 54 | 55 | } 56 | 57 | println("Total days: ", totalDays) 58 | } 59 | -------------------------------------------------------------------------------- /06-Loops/01-For/breakContinue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | for i := 1; i <= 100; i++ { 6 | if i%2 != 0 { 7 | continue 8 | } 9 | println(i) 10 | } 11 | 12 | for i := 1; i <= 100; i++ { 13 | if i == 50 { 14 | break 15 | } 16 | println(i) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /06-Loops/01-For/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "math/rand" 4 | 5 | type CreditCard struct { 6 | CardNumber string 7 | ExpireDate string 8 | Cvv2 string 9 | BankName string 10 | } 11 | 12 | func main() { 13 | 14 | cards := []CreditCard{ 15 | {CardNumber: "6037991725253535", ExpireDate: "01/01", Cvv2: "123", BankName: "Melli"}, 16 | {CardNumber: "5892101245457878", ExpireDate: "03/03", Cvv2: "245", BankName: "Sepah"}, 17 | {CardNumber: "6104981247653214", ExpireDate: "02/04", Cvv2: "741", BankName: "Mellat"}, 18 | {CardNumber: "6219861047653214", ExpireDate: "01/02", Cvv2: "1023", BankName: "Saman"}, 19 | } 20 | 21 | for _, card := range cards { 22 | 23 | if card.ExpireDate < "01/03" { 24 | println("Your card", card.CardNumber, " is expired") 25 | continue 26 | } 27 | var remainAmount = getBankAccountRemainAmount(card.CardNumber, card.ExpireDate) 28 | println("Your card", card.CardNumber, " is valid, remain amount is ", remainAmount) 29 | } 30 | 31 | } 32 | 33 | func getBankAccountRemainAmount(cardNumber string, expireDate string) int { 34 | min := 1000000 35 | max := 30000000 36 | if expireDate < "01/03" { 37 | return 0 38 | } 39 | return (rand.Intn(max-min) + min) 40 | } 41 | -------------------------------------------------------------------------------- /06-Loops/01-For/fors.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | i := 0 5 | //lst := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 6 | lst1 := []int{12, 15, 14, 13, 16, 17, 18, 19, 20, 21} 7 | for { 8 | println("Hello, world!") 9 | break 10 | } 11 | 12 | for i < 10 { 13 | println("Hello, world! ", i) 14 | i++ 15 | } 16 | 17 | for j := 0; j < 10; j++ { 18 | println("Hello, world! ", j) 19 | } 20 | 21 | for index, item := range lst1 { 22 | println("Hello, world! ", index, item) 23 | } 24 | } 25 | 26 | func twoSum(nums []int, target int) []int { 27 | 28 | for i, item := range nums { 29 | if item >= target { 30 | continue 31 | } 32 | compliment := target - item 33 | for j, itemJ := range nums { 34 | if itemJ == compliment && i != j { 35 | return []int{i, j} 36 | } 37 | } 38 | } 39 | return []int{0, 0} 40 | 41 | } 42 | 43 | // 11 * 11 = 121 44 | // 10 * 11 / 2 = 55 45 | 46 | // 110 * 110 = 12100 47 | // 110 * 109 / 2 = 5995 48 | 49 | func twoSum1(nums []int, target int) []int { 50 | 51 | // 7,11,15,45,22,10,2,8,10,12,14 52 | // 3,00,00,00,00,00,8,2,00,00,00 53 | 54 | for i, item := range nums { 55 | if item >= target { 56 | continue 57 | } 58 | compliment := target - item 59 | for j := i; j < len(nums); j++ { 60 | if nums[j] == compliment && i != j { 61 | return []int{i, j} 62 | } 63 | } 64 | } 65 | return []int{0, 0} 66 | 67 | } 68 | 69 | // [7,11,15,45,22,10,2,8,10,12,14] 70 | // 10 71 | // [3,2,41,7,6,9,8,110,14,20,25,23] 72 | // 13 73 | // [3,3] 74 | // 6 75 | 76 | func twoSum2(nums []int, target int) []int { 77 | 78 | // 7,11,15,45,22,10,2,8,10,12,14 // 121 79 | // 3,00,00,00,00,00,8,2,00,00,00 // 55 80 | keys := map[int]int{} 81 | for i, item := range nums { 82 | 83 | complement := target - item 84 | if _, exist := keys[complement]; exist { 85 | return []int{keys[complement], i} 86 | } 87 | 88 | keys[item] = i 89 | 90 | } 91 | return []int{0, 0} 92 | 93 | } 94 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/01-Array/array.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | var myArr0 [5]int 8 | var myArr1 [6]int = [6]int{1, 2} 9 | myArr2 := [7]int{1, 2} 10 | myArr3 := [...]int{1, 2} 11 | 12 | myArr0[2] = 25 13 | myArr1[5] = 25 14 | myArr2[6] = 25 15 | myArr3[1] = 25 16 | 17 | fmt.Println(myArr0) 18 | fmt.Println(myArr1) 19 | fmt.Println(myArr2) 20 | fmt.Println(myArr3) 21 | 22 | fmt.Println(len(myArr0)) 23 | fmt.Println(len(myArr1)) 24 | fmt.Println(len(myArr2)) 25 | fmt.Println(len(myArr3)) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/01-Array/copy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | numbers := [8]int{1, 2, 3, 4, 5, 6, 7, 8} 7 | 8 | numbers2 := &numbers 9 | 10 | numbers3 := numbers[:2] 11 | 12 | numbers4 := numbers3 13 | 14 | numbers[0] = 100 15 | 16 | println(&numbers) 17 | println(&numbers2) 18 | println(&numbers3) 19 | println(&numbers4) 20 | 21 | fmt.Printf("numbers: %v\n", numbers) 22 | fmt.Printf("numbers2: %v\n", numbers2) 23 | 24 | changeValue(&numbers) 25 | changeValue(numbers2) 26 | 27 | fmt.Printf("numbers: %v\n", numbers) 28 | fmt.Printf("numbers2: %v\n", numbers2) 29 | 30 | } 31 | 32 | func changeValue(mayArray *[8]int) { 33 | mayArray[0] = 555 34 | mayArray[1] = 666 35 | } 36 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/01-Array/search.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | names := [8]string{"Ali", "Reza", "Milad", "Mahtab", "Farshad", "Fereshte", "Hadi", "Mahdi"} 5 | 6 | searchKey := "Milad" 7 | 8 | for i, name := range names { 9 | if name == searchKey { 10 | println("Name found. Index: ", i) 11 | break 12 | } 13 | } 14 | 15 | for j := 0; j < len(names); j++ { 16 | if names[j] == searchKey { 17 | println("Name found. Index: ", j) 18 | break 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/SliceInitBenchmark/benchmark_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func BenchmarkInitializeSize(b *testing.B) { 8 | mySlc := make([]int, b.N) 9 | for i := 0; i < b.N; i++ { 10 | mySlc[i] = i * 2 11 | } 12 | //log.Print(len(mySlc)) 13 | } 14 | 15 | func BenchmarkNotInitializeSize(b *testing.B) { 16 | mySlc := []int{} 17 | for i := 0; i < b.N; i++ { 18 | mySlc = append(mySlc, i*2) 19 | } 20 | //log.Print(len(mySlc)) 21 | } 22 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/SliceInitBenchmark/go.mod: -------------------------------------------------------------------------------- 1 | module benchmarks 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/append.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | numbers := []int{1, 2, 3, 4, 5} 7 | numbers2 := []int{10, 20, 30, 40, 50, 60, 70, 80, 90, 100} 8 | 9 | numbers = append(numbers, 6, 7, 8, 9) 10 | 11 | fmt.Printf("%v \n", numbers) 12 | 13 | numbers = append(numbers, numbers2...) 14 | 15 | fmt.Printf("%v \n", numbers) 16 | } -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/copy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | numbers := []int{1, 2, 3, 4, 5} 7 | numbers2 := []int{10, 20, 30, 40, 50} 8 | 9 | count := copy(numbers, numbers2) 10 | 11 | fmt.Printf("%v \n", numbers) 12 | fmt.Printf("%d \n", count) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | myArray := [8]int{1, 2, 3, 4, 5, 6, 7, 8} 8 | 9 | // mySlice := []int{1, 2, 3, 4, 5, 6, 7, 8} 10 | 11 | // mySlice1 := make([]int, 8) 12 | 13 | // mySlice2 := make([]int, 8, 16) 14 | 15 | slc1 := myArray[2:6] 16 | 17 | myArray[2] = 20 18 | 19 | // fmt.Printf("%v\n", myArray) 20 | // fmt.Printf("%v\n", slc1) 21 | 22 | // fmt.Println("slc1 length: ", len(slc1)) 23 | // fmt.Println("slc1 cap: ", cap(slc1)) 24 | 25 | // fmt.Println("myArray length: ", len(myArray)) 26 | // fmt.Println("myArray cap: ", cap(myArray)) 27 | 28 | slc1 = append(slc1, 99) 29 | slc1 = append(slc1, 98) 30 | slc1 = append(slc1, 97) 31 | slc1 = append(slc1, 96, 95, 94, 93, 92, 91, 90) 32 | 33 | myArray[7] = 101 34 | 35 | fmt.Printf("%v\n", myArray) 36 | fmt.Printf("%v\n", slc1) 37 | 38 | fmt.Println("slc1 length: ", len(slc1)) 39 | fmt.Println("slc1 cap: ", cap(slc1)) 40 | 41 | fmt.Println("myArray length: ", len(myArray)) 42 | fmt.Println("myArray cap: ", cap(myArray)) 43 | } 44 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/func.go: -------------------------------------------------------------------------------- 1 | /* 07-04 2 | Send to func and problems 3 | Slice in loop and problems 4 | Copy func 5 | Merge two slice with append 6 | Prepend 7 | Remove and put 8 | Remove all 9 | Remove slice 10 | */ 11 | 12 | package main 13 | 14 | import "fmt" 15 | 16 | func main() { 17 | 18 | numbers := []int{1, 2, 3, 4, 5} 19 | 20 | addItem(&numbers) 21 | 22 | fmt.Printf("%v \n", numbers) 23 | 24 | } 25 | 26 | func changeNumbers(numbers []int) { 27 | for i := range numbers { 28 | numbers[i] = numbers[i] * 3 29 | } 30 | } 31 | 32 | func addItem(numbers *[]int){ 33 | *numbers = append(*numbers, 6) 34 | } 35 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/leetCode-twoSum.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | nums := []int{2, 7, 5, 11, 15, 5} 10 | target := 10 11 | result := twoSum(nums, target) 12 | fmt.Println(result) 13 | println(reflect.DeepEqual(result, []int{2, 5})) 14 | } 15 | 16 | func twoSum(nums []int, target int) []int { 17 | 18 | for i, item := range nums { 19 | complement := target - item 20 | for j := i + 1; j < len(nums); j++ { 21 | if i != j && nums[j] == complement { 22 | return []int{i, j} 23 | } 24 | } 25 | } 26 | return []int{0, 0} 27 | 28 | } 29 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/loop.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | 10 | names := []string{"Hamed", "Farzaneh", "Reza", "Sara"} 11 | 12 | for _, item := range names { 13 | item = strings.ToUpper(item) 14 | } 15 | 16 | fmt.Printf("%v \n", names) 17 | 18 | for i, item := range names { 19 | names[i] = strings.ToUpper(item) 20 | } 21 | 22 | fmt.Printf("%v \n", names) 23 | } 24 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/other.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 8 | 9 | // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 10 | // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 11 | // 1, 2, 3, 4, 5, 6, 7, 75, 8, 9, 10, 11, 12, 13, 14, 15 12 | numbers = append(numbers, 0) 13 | // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 14 | 15 | _ = copy(numbers[8:], numbers[7:]) 16 | // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 17 | // 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15 18 | 19 | numbers[7] = 75 20 | 21 | fmt.Printf("%v \n", numbers) 22 | 23 | numbers = append(numbers[:7],numbers[8:]...) 24 | 25 | fmt.Printf("%v \n", numbers) 26 | 27 | 28 | numbers = numbers[:0] 29 | fmt.Printf("%v \n", numbers) 30 | fmt.Printf("%d \n", len(numbers)) 31 | fmt.Printf("%d \n", cap(numbers)) 32 | 33 | 34 | 35 | numbers = nil 36 | fmt.Printf("%v \n", numbers) 37 | fmt.Printf("%d \n", len(numbers)) 38 | fmt.Printf("%d \n", cap(numbers)) 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/two_sum_bench/go.mod: -------------------------------------------------------------------------------- 1 | module two_sum 2 | 3 | go 1.19 4 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/two_sum_bench/two_sum.go: -------------------------------------------------------------------------------- 1 | package twoSum 2 | 3 | func twoSumWithMakeMap(nums []int, target int) []int { 4 | checked := make(map[int]int) 5 | for index, num := range nums { 6 | if index2, ok := checked[target-num]; ok { 7 | return []int{index2, index} 8 | } 9 | checked[num] = index 10 | } 11 | return []int{} 12 | } 13 | 14 | func twoSumWithNewMap(nums []int, target int) []int { 15 | checked := map[int]int{} 16 | for index, num := range nums { 17 | if index2, ok := checked[target-num]; ok { 18 | return []int{index2, index} 19 | } 20 | checked[num] = index 21 | } 22 | return []int{} 23 | } 24 | 25 | func twoSumWithMakeMapAndExtraAssign(nums []int, target int) []int { 26 | checked := make(map[int]int) 27 | for index, num := range nums { 28 | complete := target - num 29 | if _, ok := checked[complete]; ok { 30 | return []int{checked[complete], index} 31 | } 32 | checked[num] = index 33 | } 34 | return []int{} 35 | } 36 | 37 | func twoSumWithSlice1(nums []int, target int) []int { 38 | // 7,11,15,45,22,10,2,8,10,12,14 // 121 39 | // 3,00,00,00,00,00,8,2,00,00,00 // 55 40 | 41 | for i, item := range nums { 42 | 43 | compliment := target - item 44 | for j := i + 1; j < len(nums); j++ { 45 | if nums[j] == compliment { 46 | return []int{i, j} 47 | } 48 | } 49 | } 50 | return []int{0, 0} 51 | 52 | } 53 | 54 | func twoSumWithSlice2(nums []int, target int) []int { 55 | // 7,11,15,45,22,10,2,8,10,12,14 // 121 56 | // 3,00,00,00,00,00,8,2,00,00,00 // 55 57 | 58 | for i, item := range nums { 59 | 60 | compliment := target - item 61 | for j := i + 1; j < len(nums); j++ { 62 | if nums[j] == compliment && i != j { 63 | return []int{i, j} 64 | } 65 | } 66 | } 67 | return []int{0, 0} 68 | 69 | } 70 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/02-Slice/two_sum_bench/two_sum_test.go: -------------------------------------------------------------------------------- 1 | package twoSum 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var testCases = [][]int{ 8 | {5, 1, 6, 3, 10, 8, 12, 7, 9, 4}, // 5 9 | {11, 20, 1, 5, 9, 4, 3, 16, 18, 7}, // 13 10 | {16, 2, 9, 1, 7, 4, 18, 10, 3, 13}, // 9 11 | {81, 7, 13, 1, 4, 12, 12, 6, 9, 5}, // 15 12 | {4, 7, 2, 9, 1, 5, 8, 3, 6, 10}, // 18 13 | {3, 4, 15, 6, 2, 9, 11, 7, 10, 8}, // 7 14 | {19, 18, 15, 3, 4, 6, 2, 7, 10, -1}, // 11 15 | {10, 2, 3, 7, 4, 6, 1, 8, 5, 9}, // 3 16 | {13, 5, 1, 10, 6, 7, 19, 2, 14, 18}, // 14 17 | {7, 4, 51, 8, 10, 1, 3, 6, 2, 9}, // 6 18 | } 19 | 20 | var testTargets = []int{5, 13, 9, 15, 18, 7, 11, 3, 14, 6} 21 | 22 | var testExpected = [][]int{ 23 | {1, 9}, 24 | {4, 5}, 25 | {1, 4}, 26 | {7, 8}, 27 | {6, 9}, 28 | {0, 1}, 29 | {4, 7}, 30 | {1, 6}, 31 | {0, 2}, 32 | {1, 8}, 33 | } 34 | 35 | func BenchmarkTwoSumWithMakeMap(b *testing.B) { 36 | b.ReportAllocs() 37 | b.ResetTimer() 38 | for i := 0; i < b.N; i++ { 39 | for i, item := range testCases { 40 | twoSumWithMakeMap(item, testTargets[i]) 41 | // if result[0] != testExpected[i][0] || result[1] != testExpected[i][1] { 42 | // fmt.Printf("item %d", i) 43 | // } 44 | 45 | } 46 | } 47 | } 48 | 49 | func BenchmarkTwoSumWithNewMap(b *testing.B) { 50 | b.ReportAllocs() 51 | b.ResetTimer() 52 | for i := 0; i < b.N; i++ { 53 | for i, item := range testCases { 54 | twoSumWithNewMap(item, testTargets[i]) 55 | // if result[0] != testExpected[i][0] || result[1] != testExpected[i][1] { 56 | // fmt.Printf("item %d", i) 57 | // } 58 | 59 | } 60 | } 61 | } 62 | 63 | func BenchmarkTwoSumWithMakeMapAndExtraAssign(b *testing.B) { 64 | b.ReportAllocs() 65 | b.ResetTimer() 66 | for i := 0; i < b.N; i++ { 67 | for i, item := range testCases { 68 | twoSumWithMakeMapAndExtraAssign(item, testTargets[i]) 69 | // if result[0] != testExpected[i][0] || result[1] != testExpected[i][1] { 70 | // fmt.Printf("item %d", i) 71 | // } 72 | 73 | } 74 | } 75 | } 76 | 77 | func BenchmarkTwoSumWithSlice1(b *testing.B) { 78 | b.ReportAllocs() 79 | b.ResetTimer() 80 | for i := 0; i < b.N; i++ { 81 | for i, item := range testCases { 82 | twoSumWithSlice1(item, testTargets[i]) 83 | // if result[0] != testExpected[i][0] || result[1] != testExpected[i][1] { 84 | // fmt.Printf("item %d", i) 85 | // } 86 | 87 | } 88 | } 89 | } 90 | 91 | func BenchmarkTwoSumWithSlice2(b *testing.B) { 92 | b.ReportAllocs() 93 | b.ResetTimer() 94 | for i := 0; i < b.N; i++ { 95 | for i, item := range testCases { 96 | twoSumWithSlice2(item, testTargets[i]) 97 | // if result[0] != testExpected[i][0] || result[1] != testExpected[i][1] { 98 | // fmt.Printf("item %d", i) 99 | // } 100 | 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/03-Map/creation.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | // Map Creation: 8 | 9 | names := make(map[string]string) 10 | names1 := map[string]string{} 11 | var names2 map[string]string = map[string]string{} 12 | 13 | names["1234567890"] = "Ali Hoessini" 14 | names1["1234567890"] = "Ali Hoessini" 15 | names2["1234567890"] = "Ali Hoessini" 16 | 17 | fmt.Printf("%v\n", names) 18 | fmt.Printf("%v\n", names1) 19 | fmt.Printf("%v\n", names2) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/03-Map/crud.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | Name string 7 | Family string 8 | Age int 9 | } 10 | 11 | func main() { 12 | 13 | persons := make(map[string]Person) 14 | 15 | persons["1234567890"] = Person{Name: "Ali", Family: "Hoessini", Age: 30} 16 | persons["4832425354"] = Person{Name: "Reza", Family: "Rezaei", Age: 31} 17 | persons["8579456213"] = Person{Name: "Milad", Family: "Mohammadi", Age: 31} 18 | 19 | fmt.Printf("%v\n", persons) 20 | 21 | persons["1234567890"] = Person{Name: "Farhad", Family: "Davoodi", Age: 41} 22 | 23 | fmt.Printf("%v\n", persons) 24 | 25 | delete(persons, "8579456213") 26 | 27 | fmt.Printf("%v\n", persons) 28 | 29 | farhad, ok := persons["1234567840"] 30 | 31 | if ok { 32 | fmt.Printf("%v\n", farhad) 33 | } else { 34 | fmt.Printf("Not Found\n") 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /07-CompositeDataTypes/03-Map/other.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | Name string 7 | Family string 8 | Age int 9 | } 10 | 11 | func main() { 12 | 13 | persons := make(map[string]Person) 14 | personSlice := []string{} 15 | persons["1234567890"] = Person{Name: "Ali", Family: "Hoessini", Age: 30} 16 | personSlice = append(personSlice, "1234567890") 17 | persons["4832425354"] = Person{Name: "Reza", Family: "Rezaei", Age: 31} 18 | personSlice = append(personSlice, "4832425354") 19 | persons["8579456213"] = Person{Name: "Milad", Family: "Mohammadi", Age: 31} 20 | personSlice = append(personSlice, "8579456213") 21 | persons["9285365246"] = Person{Name: "Peyman", Family: "Rezvani", Age: 31} 22 | personSlice = append(personSlice, "9285365246") 23 | persons["6321459957"] = Person{Name: "Amir", Family: "Hamidi", Age: 31} 24 | personSlice = append(personSlice, "6321459957") 25 | persons["4563214569"] = Person{Name: "Amin", Family: "Golmahalle", Age: 31} 26 | personSlice = append(personSlice, "4563214569") 27 | 28 | fmt.Printf("%d\n", len(persons)) 29 | 30 | 31 | for _, person := range personSlice { 32 | fmt.Printf("%v\n", persons[person]) 33 | } 34 | 35 | // interview questions: 36 | // 1. Reference type or value type? 37 | // 2. Copy map 38 | persons2 := make(map[string]Person) 39 | 40 | for key, value := range persons { 41 | persons2[key] = value 42 | } 43 | 44 | // 3. Equality of maps 45 | 46 | // 4. Concurrency: 47 | // map is not thread safe 48 | // 1:1000 2:2000 3:3000 49 | // routine 1: get 1:1000, increase 1500 = 2500, set 2500 50 | // routine 2: get 1:1000, decrease 500 = 500, set 500 (overwrite) 51 | 52 | // Problem: slice of numbers and target number 53 | // sum two numbers 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /08-Function/01-intro/intro.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | Print1() 5 | str := Print2() 6 | println(str) 7 | str3 := Print3("33") 8 | println(str3) 9 | } 10 | 11 | // without input and output 12 | func Print1() { 13 | println("Hello World1") 14 | } 15 | 16 | // without input and with output 17 | func Print2() string { 18 | return "Hello World2" 19 | } 20 | 21 | // with input and output 22 | func Print3(str string) string { 23 | return "Hello World " + str 24 | } 25 | -------------------------------------------------------------------------------- /08-Function/02-MultipleReturns/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | order1, tax1 := CalculateRoomPrice("standard", 3, 2) 8 | 9 | fmt.Printf("order1 price: %d, tax1: %f\n", order1, tax1) 10 | 11 | } 12 | 13 | func CalculateRoomPrice(roomType string, nights int, personCount int) (int, float64) { 14 | var price int 15 | var tax float64 16 | 17 | switch roomType { 18 | case "standard": 19 | price = nights * 140000 * personCount 20 | case "double": 21 | price = nights * 220000 * personCount 22 | case "suite": 23 | price = nights * 350000 * personCount 24 | } 25 | 26 | tax = float64(price) * 0.09 27 | return price, tax 28 | } 29 | -------------------------------------------------------------------------------- /08-Function/03-NamedReturnValue/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | price, finalPrice, tax := CalculateRoomPrice("standard", 3, 2) 8 | 9 | fmt.Printf("order price: %d, tax: %f\n finalPrice = price + tax (%d + %f) => %d\n", price, tax, price, tax, finalPrice) 10 | 11 | } 12 | 13 | func CalculateRoomPrice(roomType string, nights int, personCount int) (price int, finalPrice int, tax float64) { 14 | 15 | switch roomType { 16 | case "standard": 17 | price = nights * 140000 * personCount 18 | case "double": 19 | price = nights * 220000 * personCount 20 | case "suite": 21 | price = nights * 350000 * personCount 22 | } 23 | 24 | tax = float64(price) * 0.09 25 | finalPrice = price + int(tax) 26 | 27 | return 28 | } 29 | -------------------------------------------------------------------------------- /08-Function/04-Variadic/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "reflect" 4 | 5 | func main() { 6 | Calculator(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "Ali") 7 | } 8 | 9 | func Calculator(numbers ...interface{}) { 10 | for _, item := range numbers { 11 | 12 | switch item.(type) { 13 | case int: 14 | println("int:", reflect.ValueOf(item).Int()) 15 | case string: 16 | println("string:", reflect.ValueOf(item).String()) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /08-Function/04-Variadic/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | sum, multiply := Calculator("Ali", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 8 | 9 | fmt.Printf("sum: %d, multiply: %d\n", sum, multiply) 10 | } 11 | 12 | func Calculator(name string, numbers ...int) (sum int, mul int) { 13 | mul = 1 14 | for _, number := range numbers { 15 | sum += number 16 | mul *= number 17 | } 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /08-Function/04-Variadic/example2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | PrintLog("Ali", 1, "Reza", 3, "Error", 5, 6, "Info", 8, 9, false) 7 | 8 | } 9 | 10 | func PrintLog(logs ...interface{}) { 11 | for i, item := range logs { 12 | fmt.Printf("%d: %v\n", i, item) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /08-Function/05-Anonymous/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | myFunc := func() { 8 | fmt.Println("Hello World") 9 | } 10 | 11 | x := 1200 12 | 13 | myFunc() 14 | myFunc() 15 | 16 | println(func(numbers ...int) int { 17 | var total int 18 | for _, number := range numbers { 19 | total += number 20 | x++ 21 | println(&x) 22 | } 23 | return total 24 | }(1, 2, 3, 4, 5)) 25 | 26 | println(x) 27 | 28 | sum := func(numbers ...int) int { 29 | var total int 30 | for _, number := range numbers { 31 | total += number 32 | x++ 33 | println(&x) 34 | } 35 | return total 36 | } 37 | 38 | println(sum(1, 2, 3, 4, 5)) 39 | println(x) 40 | println(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) 41 | println(x) 42 | 43 | } 44 | -------------------------------------------------------------------------------- /08-Function/05-Anonymous/example2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func main() { 9 | 10 | numbers := []int{12, 5, 48, 32, 1, 2, 74, 36, 90, 100, 95, 42} 11 | 12 | fmt.Printf("%v\n", numbers) 13 | 14 | sortingFunc := func(i, j int) bool { 15 | return numbers[i] < numbers[j] 16 | } 17 | sort.Slice(numbers, sortingFunc) 18 | 19 | fmt.Printf("%v\n", numbers) 20 | } 21 | -------------------------------------------------------------------------------- /08-Function/06-Clouser/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "time" 4 | 5 | func main() { 6 | firstName := "Ali" 7 | names := []string{"Ali", "Reza", "Peyman", "Pejman", "Pejman1", "Pejman2", "Pejman3", "Pejman4"} 8 | 9 | printFirstNameFunc := func() { 10 | println(firstName) 11 | } 12 | 13 | firstName = "Reza" 14 | 15 | printFirstNameFunc() 16 | 17 | //--------------------------------------- 18 | 19 | for i, name := range names { 20 | go func() { 21 | name = "*" + name 22 | println(i, name) 23 | }() 24 | } 25 | 26 | time.Sleep(time.Second * 1) 27 | 28 | for i, item := range names { 29 | go func(index int, name string) { 30 | name = "*" + name 31 | println(index, name) 32 | }(i, item) 33 | } 34 | 35 | time.Sleep(time.Second * 1) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /08-Function/07-Defer/destination.txt: -------------------------------------------------------------------------------- 1 | this is test -------------------------------------------------------------------------------- /08-Function/07-Defer/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | 10 | defer println("Bye") 11 | defer println("Good") 12 | 13 | for i := 0; i < 10; i++ { 14 | defer println(i) 15 | } 16 | 17 | println("Hello") 18 | 19 | CopyFile("F:\\GolangTutorial\\08-Function\\07-Defer\\destination.txt", "F:\\GolangTutorial\\08-Function\\07-Defer\\source.txt") 20 | 21 | } 22 | 23 | func CopyFile(destinationName, sourceName string) (written int64, err error) { 24 | 25 | source, err := os.Open(sourceName) 26 | 27 | if err != nil { 28 | return 29 | } 30 | 31 | defer source.Close() 32 | 33 | destination, err := os.Create(destinationName) 34 | 35 | if err != nil { 36 | return 37 | } 38 | 39 | defer destination.Close() 40 | 41 | return io.Copy(destination, source) 42 | 43 | } 44 | -------------------------------------------------------------------------------- /08-Function/07-Defer/source.txt: -------------------------------------------------------------------------------- 1 | this is test -------------------------------------------------------------------------------- /09-Structs/03-Instantiation/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | FirstName string 7 | LastName string 8 | Age uint 9 | } 10 | 11 | type PersonOptions struct { 12 | FirstName string 13 | LastName string 14 | Age uint 15 | } 16 | 17 | func main() { 18 | 19 | // 1 20 | person1 := Person{FirstName: "Ali", LastName: "Khan", Age: 25} 21 | 22 | // 2 23 | person2 := new(Person) 24 | person2.FirstName = "Reza" 25 | person2.LastName = "Khan" 26 | person2.Age = 30 27 | 28 | // 3 29 | person3 := &Person{FirstName: "Sara", LastName: "Khan", Age: 35} 30 | 31 | // 4 32 | person4 := NewPerson("Maryam", "Kha", 33) 33 | 34 | // 5 35 | person5 := NewPersonWithOptions(PersonOptions{FirstName: "Milad", LastName: "Khan", Age: 30}) 36 | 37 | fmt.Println(person1) 38 | fmt.Println(person2) 39 | fmt.Println(person3) 40 | fmt.Println(person4) 41 | fmt.Println(person5) 42 | 43 | } 44 | 45 | func NewPerson(FirstName, LastName string, Age uint) *Person { 46 | if len(LastName) < 4 { 47 | return nil 48 | } 49 | return &Person{FirstName: FirstName, LastName: LastName, Age: Age} 50 | } 51 | 52 | func NewPersonWithOptions(personOptions PersonOptions) *Person { 53 | if len(personOptions.LastName) < 4 { 54 | return nil 55 | } 56 | return &Person{FirstName: personOptions.FirstName, LastName: personOptions.LastName, Age: personOptions.Age} 57 | } 58 | -------------------------------------------------------------------------------- /09-Structs/04-Methods/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Employee struct { 4 | ID int 5 | Name string 6 | Type string 7 | SalaryOfMonth int 8 | } 9 | 10 | func main() { 11 | 12 | var employee1 Employee = Employee{ID: 1, Name: "Mohammad reza", Type: "Manager", SalaryOfMonth: 700} 13 | var employee2 Employee = Employee{ID: 1, Name: "Peyman", Type: "Manager", SalaryOfMonth: 750} 14 | salary1 := CalcYearlySalary(employee1) 15 | salary2 := employee1.CalcYearlySalary() 16 | salary3 := employee2.CalcYearlySalary() 17 | println(salary1) 18 | println(salary2) 19 | println(salary3) 20 | } 21 | 22 | // Function 23 | func CalcYearlySalary(employee Employee) int { 24 | return employee.SalaryOfMonth * 12 25 | } 26 | 27 | // method of Employee struct 28 | func (employee *Employee) CalcYearlySalary() int { 29 | return employee.SalaryOfMonth * 12 30 | } -------------------------------------------------------------------------------- /09-Structs/05-Abstraction/badExample.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | BaseSalary = 5600000 7 | ExtraHourRate = 90000 8 | HourlySalaryRate = 110000 9 | ShiftSalaryRate = 80000 10 | TaxRate = 0.09 11 | ) 12 | 13 | func main() { 14 | employees := []Employee{ 15 | {Id: 1, NationalCode: "1234567890", FullName: "Pejman Rezaee", Type: "FullTime", Hours: 40}, 16 | {Id: 2, NationalCode: "4836524125", FullName: "Maryam Hosseini", Type: "PartTime", Hours: 120}, 17 | {Id: 3, NationalCode: "6542541458", FullName: "Reza ", Type: "FullTime", Hours: 15.5}, 18 | {Id: 4, NationalCode: "1368245856", FullName: "Mahtab", Type: "Shift", Hours: 160}, 19 | } 20 | 21 | for _, employee := range employees { 22 | salary, tax := employee.SalaryCalculator(float64(employee.Hours)) 23 | fmt.Printf("Employee: %v\nSalary: %f\nTax: %f\n", employee, salary, tax) 24 | } 25 | } 26 | 27 | type Employee struct { 28 | Id int 29 | NationalCode string 30 | FullName string 31 | Type string 32 | Hours float64 33 | } 34 | 35 | func (employee Employee) FullTimeSalaryCalculator(extraHours float64) (salary float64, tax float64) { 36 | salary = BaseSalary + (ExtraHourRate*extraHours)*1.4 37 | tax = salary * TaxRate 38 | salary += tax 39 | return 40 | } 41 | 42 | func (employee Employee) PartTimeSalaryCalculator(hours float64) (salary float64, tax float64) { 43 | salary = HourlySalaryRate * hours 44 | tax = salary * TaxRate 45 | salary += tax 46 | return 47 | } 48 | 49 | func (employee Employee) ShiftSalaryCalculator(hours float64) (salary float64, tax float64) { 50 | salary = ShiftSalaryRate * hours 51 | tax = salary * TaxRate 52 | salary += tax 53 | return 54 | } 55 | 56 | func (employee Employee) SalaryCalculator(hours float64) (salary float64, tax float64) { 57 | if employee.Type == "FullTime" { 58 | return employee.FullTimeSalaryCalculator(hours) 59 | } else if employee.Type == "PartTime" { 60 | return employee.PartTimeSalaryCalculator(hours) 61 | } else{ 62 | return employee.ShiftSalaryCalculator(hours) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /09-Structs/06-Polymorphism/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | BaseSalary = 5600000 7 | ExtraHourRate = 90000 8 | HourlySalaryRate = 110000 9 | ShiftSalaryRate = 80000 10 | TaxRate = 0.09 11 | ) 12 | 13 | func main() { 14 | // 15 | fullTimeEmployees := []FullTimeEmployee{ 16 | {Id: 1, NationalCode: "1234567890", FullName: "Pejman Rezaee", ExtraHours: 40}, 17 | {Id: 2, NationalCode: "4836524125", FullName: "Maryam Hosseini", ExtraHours: 120}, 18 | } 19 | 20 | partTimeEmployees := []PartTimeEmployee{ 21 | {Id: 3, NationalCode: "6563453455", FullName: "Milad Hassani", PartTimeHours: 100}, 22 | {Id: 4, NationalCode: "5435435435", FullName: "Maryam Rezaee", PartTimeHours: 87}, 23 | } 24 | 25 | shiftEmployees := []ShiftEmployee{ 26 | {Id: 5, NationalCode: "3123123213", FullName: "Shahin", ShiftHours: 150}, 27 | {Id: 6, NationalCode: "6363454355", FullName: "Masoud", ShiftHours: 168}, 28 | } 29 | 30 | var employees []Employee = []Employee{} 31 | 32 | for _, employee := range fullTimeEmployees { 33 | employees = append(employees, employee) 34 | } 35 | 36 | for _, employee := range partTimeEmployees { 37 | employees = append(employees, employee) 38 | } 39 | 40 | for _, employee := range shiftEmployees { 41 | employees = append(employees, employee) 42 | } 43 | 44 | for _, employee := range employees { 45 | salary, tax := employee.SalaryCalculator() 46 | fmt.Printf("\nEmployee (%T): %v\nSalary: %f\nTax: %f\n", employee, employee, salary, tax) 47 | } 48 | 49 | } 50 | 51 | type Employee interface { 52 | SalaryCalculator() (salary float64, tax float64) 53 | } 54 | 55 | type FullTimeEmployee struct { 56 | Id int 57 | NationalCode string 58 | FullName string 59 | ExtraHours float64 60 | } 61 | 62 | type PartTimeEmployee struct { 63 | Id int 64 | NationalCode string 65 | FullName string 66 | PartTimeHours float64 67 | } 68 | 69 | type ShiftEmployee struct { 70 | Id int 71 | NationalCode string 72 | FullName string 73 | ShiftHours float64 74 | } 75 | 76 | func (employee FullTimeEmployee) SalaryCalculator() (salary float64, tax float64) { 77 | salary = BaseSalary + (ExtraHourRate*employee.ExtraHours)*1.4 78 | tax = salary * TaxRate 79 | salary += tax 80 | return 81 | } 82 | 83 | func (employee PartTimeEmployee) SalaryCalculator() (salary float64, tax float64) { 84 | salary = HourlySalaryRate * employee.PartTimeHours 85 | tax = salary * TaxRate 86 | salary += tax 87 | return 88 | } 89 | 90 | func (employee ShiftEmployee) SalaryCalculator() (salary float64, tax float64) { 91 | salary = ShiftSalaryRate * employee.ShiftHours 92 | tax = salary * TaxRate 93 | salary += tax 94 | return 95 | } -------------------------------------------------------------------------------- /09-Structs/06-Polymorphism/ticketing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type BusTicket struct { 6 | Id int 7 | DepartureCity string 8 | ArrivalCity string 9 | DepartureTime string 10 | BusType string 11 | PassengerName string 12 | DepartureTerminal string 13 | ArrivalTerminal string 14 | NationalCode string 15 | Price int 16 | } 17 | 18 | type FlightTicket struct { 19 | Id int 20 | DepartureAirport string 21 | ArrivalAirport string 22 | DepartureTime string 23 | ArrivalTime string 24 | AirplaneType string 25 | PassengerName string 26 | PassportId string 27 | PassengerType string 28 | Price int 29 | } 30 | 31 | func main() { 32 | 33 | busTicket := BusTicket{ 34 | Id: 1, 35 | DepartureCity: "Tehran", 36 | ArrivalCity: "Mashhad", 37 | DepartureTime: "12:00", 38 | BusType: "Bus", 39 | PassengerName: "Reza kamali", 40 | DepartureTerminal: "Terminal 1", 41 | ArrivalTerminal: "Terminal 2", 42 | NationalCode: "123456789", 43 | Price: 100, 44 | } 45 | 46 | flightTicket := FlightTicket{ 47 | Id: 2, 48 | DepartureAirport: "Tehran", 49 | ArrivalAirport: "London", 50 | DepartureTime: "12:00", 51 | ArrivalTime: "23:00", 52 | AirplaneType: "Airbus", 53 | PassengerName: "Peyman Hassani", 54 | PassportId: "312321414", 55 | PassengerType: "Adult", 56 | Price: 1890, 57 | } 58 | 59 | printer := []TicketPrinter{busTicket, flightTicket} 60 | 61 | for _, printer := range printer { 62 | printer.PrintTicket() 63 | } 64 | 65 | 66 | 67 | } 68 | 69 | type TicketPrinter interface { 70 | PrintTicket() 71 | } 72 | 73 | func (ticket BusTicket) PrintTicket() { 74 | fmt.Printf("Bus Ticket:\n ID: %d\n DepartureCity : %s\n ArrivalCity : %s\n DepartureTime : %s\n", ticket.Id, ticket.DepartureCity, ticket.ArrivalCity, ticket.DepartureTime) 75 | fmt.Printf("BusType : %s\n PassengerName : %s\n DepartureTerminal : %s\n ArrivalTerminal : %s\n", ticket.BusType, ticket.PassengerName, ticket.DepartureTerminal, ticket.ArrivalTerminal) 76 | fmt.Printf("NationalCode : %s\n Price : %d\n", ticket.NationalCode, ticket.Price) 77 | } 78 | 79 | func (ticket FlightTicket) PrintTicket() { 80 | fmt.Printf("Flight Ticket:\n ID: %d\n DepartureAirport : %s\n ArrivalAirport : %s\n DepartureTime : %s\n ArrivalTime : %s\n", ticket.Id, ticket.DepartureAirport, ticket.ArrivalAirport, ticket.DepartureTime,ticket.ArrivalTime) 81 | fmt.Printf("AirplaneType : %s\n PassengerName : %s\n PassportId : %s\n PassengerType : %s\n", ticket.AirplaneType, ticket.PassengerName, ticket.PassportId, ticket.PassengerType) 82 | fmt.Printf("Price : %d\n", ticket.Price) 83 | } -------------------------------------------------------------------------------- /09-Structs/07-Encapsulation/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Test struct { 6 | Id int 7 | name string 8 | } 9 | 10 | func main() { 11 | test := Test{Id: 1, name: "test"} 12 | test.Print() 13 | test.print2() 14 | } 15 | 16 | func (test Test) Print() { 17 | fmt.Println(test.Id, test.name) 18 | } 19 | func (test Test) print2() { 20 | fmt.Println(test.Id, test.name) 21 | } 22 | 23 | func AddToShoppingCart(productId int, userId int, quantity int) { 24 | checkUserStatus(userId) 25 | checkProductStatus(productId) 26 | checkQuantity(productId,quantity) 27 | checkPriceChanges(productId) 28 | addToCart(productId,quantity) 29 | updateShoppingCartTotalPrice() 30 | } 31 | 32 | func checkUserStatus(userId int) { 33 | // check user status 34 | } 35 | 36 | func checkProductStatus(productId int) { 37 | // check product status 38 | } 39 | 40 | func checkQuantity(productId int, quantity int) { 41 | // check product quantity 42 | } 43 | 44 | func checkPriceChanges(productId int) { 45 | // check price changes 46 | } 47 | 48 | func addToCart(productId int, quantity int) { 49 | // add to cart 50 | } 51 | 52 | func updateShoppingCartTotalPrice() { 53 | // update shopping cart total price 54 | } -------------------------------------------------------------------------------- /09-Structs/08-EmbededStructs/CsharpInheritance/CsharpInheritance.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | net6.0 5 | enable 6 | disable 7 | 10 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /09-Structs/08-EmbededStructs/CsharpInheritance/CsharpInheritance.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.001.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CsharpInheritance", "CsharpInheritance.csproj", "{DBCB0792-47DD-4928-A265-0431ADCE133C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DBCB0792-47DD-4928-A265-0431ADCE133C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DBCB0792-47DD-4928-A265-0431ADCE133C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DBCB0792-47DD-4928-A265-0431ADCE133C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DBCB0792-47DD-4928-A265-0431ADCE133C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {1D0FE884-0EB8-48FB-AAA0-D88CD6DBCA7E} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /09-Structs/08-EmbededStructs/CsharpInheritance/GoodExample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Good 5 | { 6 | public class Example 7 | { 8 | public static void Call() 9 | { 10 | 11 | var mobile = new Mobile { Name = "Samsung M510" }; 12 | mobile.Brand = "Samsung"; 13 | mobile.Color = "Blue"; 14 | mobile.Ram = 4; 15 | mobile.OperatingSystem = "Android"; 16 | mobile.OperatingSystemVersion = "11"; 17 | 18 | mobile.CameraCount = 2; 19 | mobile.NetworkType = "5G"; 20 | mobile.SimcardType = "Nano"; 21 | mobile.SimcardCapacity = 3; 22 | 23 | var loptop = new Loptop { Name = "MSI GX4450" }; 24 | 25 | loptop.Brand = "MSI"; 26 | loptop.Color = "Black"; 27 | loptop.Ram = 16; 28 | loptop.OperatingSystem = "Ubuntu"; 29 | loptop.OperatingSystemVersion = "22.04"; 30 | 31 | loptop.HasCdRom = false; 32 | loptop.UsbPortCount = 3; 33 | loptop.KeyboardType = "Light"; 34 | 35 | Console.WriteLine(JsonConvert.SerializeObject(mobile)); 36 | Console.WriteLine(JsonConvert.SerializeObject(loptop)); 37 | } 38 | } 39 | 40 | //////////////////////////////////////////// 41 | 42 | public abstract class Product 43 | { 44 | public string Name { get; set; } 45 | public string Color { get; set; } 46 | public float Length { get; set; } 47 | public float Width { get; set; } 48 | public float Weight { get; set; } 49 | public decimal Price { get; set; } 50 | public string Brand { get; set; } 51 | public string MadeIn { get; set; } 52 | } 53 | 54 | public abstract class ElectronicProduct : Product 55 | { 56 | public int Ram { get; set; } 57 | public string Cpu { get; set; } 58 | public float ScreenSize { get; set; } 59 | public string OperatingSystem { get; set; } 60 | public string OperatingSystemVersion { get; set; } 61 | 62 | } 63 | 64 | public class Mobile : ElectronicProduct 65 | { 66 | 67 | public int SimcardCapacity { get; set; } 68 | public string SimcardType { get; set; } 69 | public string NetworkType { get; set; } 70 | public int CameraCount { get; set; } 71 | 72 | } 73 | 74 | public class Loptop : ElectronicProduct 75 | { 76 | public int UsbPortCount { get; set; } 77 | public string KeyboardType { get; set; } 78 | public bool HasCdRom { get; set; } 79 | 80 | } 81 | } -------------------------------------------------------------------------------- /09-Structs/08-EmbededStructs/CsharpInheritance/Program.cs: -------------------------------------------------------------------------------- 1 | namespace CsharpInheritance 2 | { 3 | public class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | if (args.Length > 0 && args?[0] == "good") 8 | Good.Example.Call(); 9 | else 10 | Bad.Example.Call(); 11 | 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /09-Structs/08-EmbededStructs/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "encoding/json" 4 | 5 | type Product struct { 6 | Name string 7 | Color string 8 | Length int 9 | Width int 10 | Weight int 11 | Price int 12 | Brand string 13 | MadeIn string 14 | } 15 | 16 | type ElectronicProduct struct { 17 | Product 18 | Ram int 19 | Cpu string 20 | ScreenSize float32 21 | OperatingSystem string 22 | OperatingSystemVersion string 23 | } 24 | 25 | type Mobile struct { 26 | ElectronicProduct 27 | SimcardCapacity int 28 | SimcardType string 29 | NetworkType string 30 | CameraCount int 31 | } 32 | 33 | type Loptop struct { 34 | ElectronicProduct 35 | UsbPortCount int 36 | KeyboardType string 37 | HasCdRom bool 38 | } 39 | 40 | func main() { 41 | 42 | mobile := Mobile{} 43 | mobile.Name = "Samsung M4150" 44 | mobile.Brand = "Samsung" 45 | mobile.Color = "Blue" 46 | mobile.Ram = 4 47 | mobile.OperatingSystem = "Android" 48 | mobile.OperatingSystemVersion = "11" 49 | 50 | mobile.CameraCount = 2 51 | mobile.NetworkType = "5G" 52 | mobile.SimcardType = "Nano" 53 | mobile.SimcardCapacity = 3 54 | 55 | loptop := Loptop{} 56 | 57 | loptop.Name = "MSI GX 4570" 58 | loptop.Brand = "MSI" 59 | loptop.Color = "Black" 60 | loptop.Ram = 16 61 | loptop.OperatingSystem = "Ubuntu" 62 | loptop.OperatingSystemVersion = "22.04" 63 | 64 | loptop.HasCdRom = false 65 | loptop.UsbPortCount = 3 66 | loptop.KeyboardType = "Light" 67 | 68 | mobileJson, _ := json.Marshal(mobile) 69 | loptopJson, _ := json.Marshal(loptop) 70 | 71 | println(string(mobileJson)) 72 | println(string(loptopJson)) 73 | 74 | } 75 | -------------------------------------------------------------------------------- /09-Structs/08-EmbededStructs/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestMain(t *testing.T) { 9 | type testCase struct { 10 | Name string 11 | } 12 | 13 | validate := func(t *testing.T, tc *testCase) { 14 | t.Run(tc.Name, func(t *testing.T) { 15 | main() 16 | }) 17 | } 18 | 19 | validate(t, &testCase{}) 20 | } 21 | -------------------------------------------------------------------------------- /09-Structs/09-Composition/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | BaseSalary = 5600000 7 | ExtraHourRate = 90000 8 | HourlySalaryRate = 110000 9 | ShiftSalaryRate = 80000 10 | TaxRate = 0.09 11 | ) 12 | 13 | func main() { 14 | // 15 | fullTimeEmployees := []FullTimeEmployee{ 16 | {Employee: Employee{ Id: 1, NationalCode: "1234567890", FullName: "Pejman Rezaee"}, ExtraHours: 40}, 17 | {Employee: Employee{ Id: 2, NationalCode: "4836524125", FullName: "Maryam Hosseini"}, ExtraHours: 120}, 18 | } 19 | 20 | partTimeEmployees := []PartTimeEmployee{ 21 | {Employee: Employee{ Id: 3, NationalCode: "6563453455", FullName: "Milad Hassani"}, PartTimeHours: 100}, 22 | {Employee: Employee{ Id: 4, NationalCode: "5435435435", FullName: "Maryam Rezaee"}, PartTimeHours: 87}, 23 | } 24 | 25 | shiftEmployees := []ShiftEmployee{ 26 | {Employee: Employee{ Id: 5, NationalCode: "3123123213", FullName: "Shahin"}, ShiftHours: 150}, 27 | {Employee: Employee{ Id: 6, NationalCode: "6363454355", FullName: "Masoud"}, ShiftHours: 168}, 28 | } 29 | 30 | var employees []EmployeeSalaryCalculator = []EmployeeSalaryCalculator{} 31 | 32 | for _, employee := range fullTimeEmployees { 33 | employees = append(employees, employee) 34 | } 35 | 36 | for _, employee := range partTimeEmployees { 37 | employees = append(employees, employee) 38 | } 39 | 40 | for _, employee := range shiftEmployees { 41 | employees = append(employees, employee) 42 | } 43 | 44 | for _, employee := range employees { 45 | salary, tax := employee.SalaryCalculate() 46 | fmt.Printf("\nEmployee (%T): %v\nSalary: %f\nTax: %f\n", employee, employee, salary, tax) 47 | } 48 | 49 | } 50 | 51 | type EmployeeSalaryCalculator interface { 52 | SalaryCalculate() (salary float64, tax float64) 53 | } 54 | 55 | type Employee struct{ 56 | Id int 57 | NationalCode string 58 | FullName string 59 | Unit string 60 | } 61 | 62 | type FullTimeEmployee struct { 63 | Employee 64 | ExtraHours float64 65 | } 66 | 67 | type PartTimeEmployee struct { 68 | Employee 69 | PartTimeHours float64 70 | } 71 | 72 | type ShiftEmployee struct { 73 | Employee 74 | ShiftHours float64 75 | } 76 | 77 | func (employee FullTimeEmployee) SalaryCalculate() (salary float64, tax float64) { 78 | salary = BaseSalary + (ExtraHourRate*employee.ExtraHours)*1.4 79 | tax = salary * TaxRate 80 | salary += tax 81 | return 82 | } 83 | 84 | func (employee PartTimeEmployee) SalaryCalculate() (salary float64, tax float64) { 85 | salary = HourlySalaryRate * employee.PartTimeHours 86 | tax = salary * TaxRate 87 | salary += tax 88 | return 89 | } 90 | 91 | func (employee ShiftEmployee) SalaryCalculate() (salary float64, tax float64) { 92 | salary = ShiftSalaryRate * employee.ShiftHours 93 | tax = salary * TaxRate 94 | salary += tax 95 | return 96 | } 97 | -------------------------------------------------------------------------------- /09-Structs/10-FunctionalOptionsPattern/builder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | Name string 7 | Age int 8 | Family string 9 | Gender string 10 | Height int 11 | Weight int 12 | HairColor string 13 | } 14 | 15 | type PersonBuilder struct { 16 | Person 17 | } 18 | 19 | func main() { 20 | 21 | // 1 22 | person := Person{Name: "Alireza", Age: 23} 23 | 24 | person.Family = "Rezaei" 25 | 26 | // 2 - builder pattern 27 | personBuilder := &PersonBuilder{} 28 | person2 := personBuilder.SetName("Maryam").SetFamily("Rezaei").SetAge(23).SetGender("Female").SetHairColor("Black").SetHeight(180).SetWeight(76).Build() 29 | 30 | fmt.Printf("Person1: %+v \n", person) 31 | fmt.Printf("Person2: %+v \n", person2) 32 | } 33 | 34 | func (builder *PersonBuilder) SetName(name string) *PersonBuilder { 35 | builder.Name = name 36 | return builder 37 | } 38 | 39 | func (builder *PersonBuilder) SetFamily(family string) *PersonBuilder { 40 | builder.Family = family 41 | return builder 42 | } 43 | 44 | func (builder *PersonBuilder) SetGender(gender string) *PersonBuilder { 45 | builder.Gender = gender 46 | return builder 47 | } 48 | 49 | func (builder *PersonBuilder) SetAge(age int) *PersonBuilder { 50 | builder.Age = age 51 | return builder 52 | } 53 | 54 | func (builder *PersonBuilder) SetHeight(height int) *PersonBuilder { 55 | builder.Height = height 56 | return builder 57 | } 58 | 59 | func (builder *PersonBuilder) SetWeight(weight int) *PersonBuilder { 60 | builder.Weight = weight 61 | return builder 62 | } 63 | 64 | func (builder *PersonBuilder) SetHairColor(hairColor string) *PersonBuilder { 65 | builder.HairColor = hairColor 66 | return builder 67 | } 68 | 69 | func (builder *PersonBuilder) Build() Person { 70 | return builder.Person 71 | } 72 | 73 | // Query builder 74 | // if(name != nil) 75 | // db.Persons 76 | // .Where("Name = 'Ali'") 77 | // .Where("Family = 'Rezaei'") 78 | // .Select("Name, Family") 79 | // Result => select name,family from persons where name = 'Ali' and family = 'Rezaei' -------------------------------------------------------------------------------- /09-Structs/10-FunctionalOptionsPattern/exampleWithFOP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | Name string 7 | Age int 8 | Family string 9 | Gender string 10 | Height int 11 | Weight int 12 | HairColor string 13 | } 14 | 15 | type PersonOptions func(*Person) 16 | 17 | func main() { 18 | 19 | person := NewPerson(SetName("Maryam"), SetFamily("Rezaei"), SetAge(23), SetGender("Female"), SetHeight(175), SetWeight(70), SetHairColor("Black")) 20 | 21 | fmt.Printf("Person : %+v" , person) 22 | 23 | } 24 | 25 | func NewPerson(options ...PersonOptions) *Person { 26 | person := &Person{Name: "Alireza", Age: 23} 27 | for _, option := range options { 28 | option(person) 29 | } 30 | return person 31 | } 32 | 33 | func SetName(name string) PersonOptions { 34 | return func(person *Person) { 35 | person.Name = name 36 | } 37 | } 38 | 39 | func SetAge(age int) PersonOptions { 40 | return func(person *Person) { 41 | person.Age = age 42 | } 43 | } 44 | 45 | func SetFamily(family string) PersonOptions { 46 | return func(person *Person) { 47 | person.Family = family 48 | } 49 | } 50 | 51 | func SetGender(gender string) PersonOptions { 52 | return func(person *Person) { 53 | person.Gender = gender 54 | } 55 | } 56 | 57 | func SetHeight(height int) PersonOptions { 58 | return func(person *Person) { 59 | person.Height = height 60 | } 61 | } 62 | 63 | func SetWeight(weight int) PersonOptions { 64 | return func(person *Person) { 65 | person.Weight = weight 66 | } 67 | } 68 | 69 | func SetHairColor(hairColor string) PersonOptions { 70 | return func(person *Person) { 71 | person.HairColor = hairColor 72 | } 73 | } -------------------------------------------------------------------------------- /09-Structs/11-StructTags/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "encoding/xml" 6 | ) 7 | 8 | type Person struct { 9 | Name string `json:"first_name" xml:"name"` 10 | Age int `json:"age,omitempty" xml:"age"` 11 | Family string `json:"last_name" xml:"lastName"` 12 | Gender string `json:"gender" xml:"gender"` 13 | Height int `json:"height" xml:"height"` 14 | Weight int `json:"weight" xml:"weight"` 15 | HairColor string `json:"hair_color" xml:"hairColor"` 16 | } 17 | 18 | func main() { 19 | person := Person{Name: "Milad", Family: "Haddadi",Gender: "Male", Height: 170, Weight: 70, HairColor: "Black"} 20 | 21 | personJson, _ := json.MarshalIndent(person, "", " ") 22 | 23 | println(string(personJson)) 24 | 25 | personJson, _ = xml.MarshalIndent(person, "", " ") 26 | 27 | println(string(personJson)) 28 | } 29 | 30 | 31 | // Search Orders: OrderFilterDto 32 | // passengerName `json:"passengerName" xml:"passengerName" dbField:"passenger.name" ` -------------------------------------------------------------------------------- /09-Structs/12-AnonymousStructs/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct{ 6 | int 7 | string 8 | float64 9 | } 10 | 11 | func main() { 12 | 13 | // API call and get response 14 | 15 | apiResponse := struct { 16 | ResultCode int 17 | ResultMessage string 18 | TransactionAmount float64 19 | TransactionTime string 20 | }{ 21 | ResultCode: 0, 22 | ResultMessage: "Success", 23 | TransactionAmount: 100, 24 | TransactionTime: "2020-01-01T00:00:00", 25 | } 26 | 27 | fmt.Printf("API Response: %+v \n", apiResponse) 28 | 29 | 30 | person := Person{1,"Alireza",19.75} 31 | 32 | fmt.Printf("Person: %+v \n", person) 33 | } -------------------------------------------------------------------------------- /10-Interfaces/02-Diffs/Example.cs: -------------------------------------------------------------------------------- 1 | public interface IPerson 2 | { 3 | string Name { get; set; } 4 | int Age { get; set; } 5 | void Print() 6 | { 7 | Console.WriteLine($"{Name} {Age}"); 8 | } 9 | } 10 | 11 | public class Person : IPerson 12 | { 13 | public string Name { get; set; } 14 | public int Age { get; set; } 15 | public void Print() 16 | { 17 | Console.WriteLine("{0} - {1}", Name, Age); 18 | } 19 | } -------------------------------------------------------------------------------- /10-Interfaces/02-Diffs/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type IPerson interface { 6 | print() 7 | } 8 | 9 | type Person struct { 10 | } 11 | 12 | func main() { 13 | var p IPerson 14 | p = Person{} 15 | p.print() 16 | print2(p) 17 | print2(12) 18 | print2("ali") 19 | } 20 | 21 | func (person Person) print() { 22 | println("Hello") 23 | } 24 | 25 | func print2(item interface{}) { 26 | fmt.Printf("%v\n",item) 27 | } -------------------------------------------------------------------------------- /10-Interfaces/02-Diffs/example.ts: -------------------------------------------------------------------------------- 1 | interface IPerson { 2 | name: string; 3 | age: number; 4 | print(); 5 | 6 | } 7 | 8 | class Person implements IPerson { 9 | name: string; 10 | age: number; 11 | print() { 12 | console.log(this.name); 13 | } 14 | } -------------------------------------------------------------------------------- /10-Interfaces/03-Interface/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Runner interface { 6 | Run() 7 | } 8 | 9 | type Walker interface { 10 | Walk() 11 | } 12 | 13 | type Shooter interface { 14 | Shoot() 15 | } 16 | 17 | type ShooterRunner interface { 18 | Runner 19 | Shooter 20 | } 21 | 22 | type Player struct { 23 | Name string 24 | Age int 25 | Height int 26 | Weight int 27 | Position string 28 | } 29 | 30 | func main() { 31 | 32 | player1 := &Player{ 33 | Name: "Alireza", 34 | Age: 30, 35 | Height: 180, 36 | Weight: 70, 37 | Position: "Forward", 38 | } 39 | 40 | var runner ShooterRunner = player1 41 | 42 | var shooter ShooterRunner = player1 43 | 44 | runner.Run() 45 | 46 | shooter.Shoot() 47 | } 48 | 49 | func (player *Player) Run() { 50 | fmt.Printf("name: %s, position: %s , Player is running\n",player.Name,player.Position) 51 | } 52 | func (player *Player) Shoot() { 53 | fmt.Printf("name: %s, position: %s , Player is shooting",player.Name,player.Position) 54 | } -------------------------------------------------------------------------------- /10-Interfaces/04-EmbeddedInterfaces/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Animal interface { 6 | Eat() 7 | Sleep() 8 | Walk() 9 | } 10 | 11 | type Human interface { 12 | Animal 13 | Speak() 14 | Think() 15 | } 16 | 17 | type Employee struct { 18 | Human 19 | Name string 20 | Age int 21 | } 22 | 23 | type Cat struct { 24 | Name string 25 | } 26 | 27 | func main() { 28 | employee := &Employee{Name: "Ali", Age: 30} 29 | cat := &Cat{Name: "Cat"} 30 | 31 | var human Human = employee 32 | var animal Animal = cat 33 | 34 | human.Eat() 35 | human.Sleep() 36 | human.Walk() 37 | human.Speak() 38 | human.Think() 39 | 40 | animal.Eat() 41 | animal.Sleep() 42 | animal.Walk() 43 | } 44 | 45 | func (cat *Cat) Eat() { 46 | fmt.Println("Cat is eating") 47 | } 48 | 49 | func (cat *Cat) Sleep() { 50 | fmt.Println("Cat is sleeping") 51 | } 52 | 53 | func (cat *Cat) Walk() { 54 | fmt.Println("Cat is walking") 55 | } 56 | 57 | func (employee *Employee) Speak() { 58 | fmt.Println("Employee is speaking") 59 | } 60 | 61 | func (employee *Employee) Think() { 62 | fmt.Println("Employee is thinking") 63 | } 64 | 65 | func (employee *Employee) Eat() { 66 | fmt.Println("Employee is eating") 67 | } 68 | 69 | func (employee *Employee) Sleep() { 70 | fmt.Println("Employee is sleeping") 71 | } 72 | 73 | func (employee *Employee) Walk() { 74 | fmt.Println("Employee is walking") 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /10-Interfaces/05-EmptyInterfaces/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Person struct { 6 | Name string 7 | } 8 | func main() { 9 | Print("Hello") 10 | Print(123) 11 | Print(true) 12 | Print([]int{1, 2, 3}) 13 | Print(map[string]int{"a": 1, "b": 2}) 14 | Print(Person{"Ali"}) 15 | } 16 | 17 | func AddOrder(order interface{}) interface{}{ 18 | 19 | if 1 == 2{ 20 | return 1 21 | } 22 | 23 | if 1 == 3{ 24 | return "Cancel" 25 | } 26 | 27 | if 1 == 4{ 28 | return true 29 | } 30 | 31 | if 1 == 4{ 32 | return false 33 | } 34 | 35 | return "OK" 36 | } 37 | 38 | func Print(input interface{}) { 39 | switch input.(type) { 40 | case string: 41 | fmt.Println("String:", input) 42 | case int: 43 | fmt.Println("Integer:", input) 44 | case bool: 45 | fmt.Println("Boolean:", input) 46 | case []int: 47 | fmt.Println("Slice:", input) 48 | case map[string]int: 49 | fmt.Println("Map:", input) 50 | case Person: 51 | fmt.Println("Person:", input) 52 | } 53 | } 54 | 55 | 56 | // object -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/entities/notificationType.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | type NotificationType string 4 | 5 | const ( 6 | Email NotificationType = "Email" 7 | Sms NotificationType = "Sms" 8 | ) 9 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/entities/order.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | type Order struct { 4 | ID int64 5 | UserFullName string 6 | UserId string 7 | Price float64 8 | Status bool 9 | NotificationType NotificationType 10 | } 11 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/externalServices/emailService.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import ( 4 | "fmt" 5 | "notification/entities" 6 | ) 7 | 8 | type EmailService struct { 9 | } 10 | 11 | func (e *EmailService) SendMessage(order *entities.Order) { 12 | fmt.Printf("Email sent: %v\n", order) 13 | } 14 | 15 | func (e *EmailService) SendNotify(receiver string, message string) { 16 | fmt.Printf("Email sent: receiver: %s, message: %s\n", receiver, message) 17 | } 18 | 19 | func NewEmailService() *EmailService { 20 | return &EmailService{} 21 | } -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/externalServices/nilNotifyService.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import "fmt" 4 | 5 | type NilNotifyService struct { 6 | } 7 | 8 | func (e *NilNotifyService) SendNotify(receiver string, message string) { 9 | fmt.Printf("nilNotifyService: receiver: %s, message: %s\n", receiver, message) 10 | } 11 | 12 | func NewNilNotifyService() *NilNotifyService { 13 | return &NilNotifyService{} 14 | } 15 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/externalServices/notifier.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import "notification/entities" 4 | 5 | type Notifier interface { 6 | SendNotify(receiver string, message string) 7 | } 8 | 9 | func NewNotifier(notificationType entities.NotificationType) Notifier { 10 | switch notificationType { 11 | case entities.Sms: 12 | return NewSmsService() 13 | case entities.Email: 14 | return NewEmailService() 15 | default: 16 | return NewNilNotifyService() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/externalServices/smsService.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import ( 4 | "fmt" 5 | "notification/entities" 6 | ) 7 | 8 | type SmsService struct { 9 | } 10 | 11 | func (e *SmsService) SendMessage(order *entities.Order) { 12 | fmt.Printf("sms sent: %v\n", order) 13 | } 14 | 15 | func (e *SmsService) SendNotify(receiver string, message string) { 16 | fmt.Printf("sms sent: receiver: %s, message: %s\n", receiver, message) 17 | } 18 | 19 | func NewSmsService() *SmsService { 20 | return &SmsService{} 21 | } 22 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/go.mod: -------------------------------------------------------------------------------- 1 | module notification 2 | 3 | go 1.18 4 | 5 | require github.com/naeemaei/golangTestMod v0.0.2 // indirect 6 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/go.sum: -------------------------------------------------------------------------------- 1 | github.com/naeemaei/golangTestMod v0.0.2 h1:92cnJZKdQGaQeNdxbl1z73tTY2lunCqFMQLTKrv5eDk= 2 | github.com/naeemaei/golangTestMod v0.0.2/go.mod h1:nJJTUYiriqnqyOiC89eiyllcNpQ8pWf8dCiNeJQ4IUM= 3 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/main.go: -------------------------------------------------------------------------------- 1 | // main -> orderService -> emailService || smsService 2 | package main 3 | 4 | import ( 5 | "notification/entities" 6 | "notification/services" 7 | ) 8 | 9 | func main() { 10 | 11 | order1 := entities.Order{ 12 | ID: 1, 13 | UserFullName: "John Doe", 14 | UserId: "09115252524", 15 | Price: float64(100), 16 | Status: true, 17 | NotificationType: entities.Email, 18 | } 19 | order2 := entities.Order{ 20 | ID: 2, 21 | UserFullName: "John Mac", 22 | UserId: "09123332221", 23 | Price: float64(220), 24 | Status: true, 25 | NotificationType: entities.Sms, 26 | } 27 | 28 | order3 := entities.Order{ 29 | ID: 3, 30 | UserFullName: "Reza Mac", 31 | UserId: "09991252525", 32 | Price: float64(210), 33 | Status: true, 34 | NotificationType: "", 35 | } 36 | 37 | orderService := services.NewOrderService() 38 | orderService.CreateOrder(&order1) 39 | 40 | orderService.CreateOrder(&order2) 41 | 42 | orderService.CreateOrder(&order3) 43 | } 44 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notification/services/orderService.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "fmt" 5 | "notification/entities" 6 | "notification/externalServices" 7 | ) 8 | 9 | type OrderService struct { 10 | externalServices.Notifier 11 | } 12 | 13 | func (orderService *OrderService) CreateOrder(order *entities.Order) *entities.Order { 14 | fmt.Printf("Order created: %v\n", order) 15 | 16 | orderService.Notifier = externalServices.NewNotifier(order.NotificationType) 17 | 18 | orderService.SendNotify(order.UserId, "Order created") 19 | 20 | return order 21 | } 22 | 23 | func NewOrderService() *OrderService { 24 | return &OrderService{} 25 | } 26 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Package", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceRoot}", 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/consts/notificationType.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | type NotificationType string 4 | 5 | const ( 6 | Email NotificationType = "Email" 7 | SMS NotificationType = "SMS" 8 | ) 9 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/entities/user.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import "notification/consts" 4 | 5 | type User struct { 6 | Name string 7 | Email string 8 | Mobile string 9 | consts.NotificationType 10 | } 11 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/go.mod: -------------------------------------------------------------------------------- 1 | module notification 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "notification/consts" 5 | "notification/entities" 6 | "notification/services" 7 | ) 8 | 9 | func main() { 10 | ali := entities.User{Name: "Ali", Email: "ali@ali.com", Mobile: "09121231231", NotificationType: consts.Email} 11 | mojtaba := entities.User{Name: "Mottaba", Email: "mojtaba@mojtaba.com", Mobile: "09123322114", NotificationType: consts.SMS} 12 | 13 | services.NewNotifier(mojtaba.NotificationType).Notify("Hello", mojtaba.Mobile) 14 | services.NewNotifier(ali.NotificationType).Notify("Hello", mojtaba.Email) 15 | } 16 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/notification.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naeemaei/Golang-Tutorial/a5e0b8af03294841921740f8925fbd107cda8182/10-Interfaces/06-MiniProject/01-Notifier/notification.exe -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/01-Notifier/services/notifier.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "fmt" 5 | consts "notification/consts" 6 | ) 7 | 8 | type Notifier interface { 9 | Notify(receiver string, message string) 10 | } 11 | 12 | type emailService struct { 13 | } 14 | 15 | type smsService struct { 16 | } 17 | 18 | func (notifier emailService) Notify(receiver string, message string) { 19 | fmt.Println(message, " sent to email", receiver) 20 | } 21 | 22 | func (notifier smsService) Notify(receiver string, message string) { 23 | fmt.Println(message, " sent to mobile", receiver) 24 | } 25 | 26 | func NewNotifier(notificationType consts.NotificationType) Notifier { 27 | switch notificationType { 28 | case consts.Email: 29 | return emailService{} 30 | case consts.SMS: 31 | return smsService{} 32 | } 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/project.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type NotificationType string 6 | 7 | const ( 8 | Email NotificationType = "Email" 9 | SMS NotificationType = "SMS" 10 | ) 11 | 12 | type Notifier interface { 13 | Notify(receiver string, message string) 14 | } 15 | 16 | type emailNotifier struct { 17 | } 18 | 19 | type smsNotifier struct { 20 | } 21 | 22 | type User struct { 23 | Name string 24 | Email string 25 | Mobile string 26 | NotificationType 27 | } 28 | 29 | type UserService struct{ 30 | Notifier 31 | } 32 | 33 | func main() { 34 | ali := User{Name: "Ali", Email: "ali@ali.com", Mobile: "09121231231", NotificationType: Email} 35 | mojtaba := User{Name: "Mottaba", Email: "mojtaba@mojtaba.com", Mobile: "09123322114", NotificationType: SMS} 36 | 37 | NewNotifier(mojtaba.NotificationType).Notify("Hello",mojtaba.Mobile) 38 | NewNotifier(ali.NotificationType).Notify("Hello",mojtaba.Email) 39 | } 40 | 41 | func (user *User) Notify(message string) { 42 | switch user.NotificationType { 43 | case Email: 44 | fmt.Println("Email sent to", user.Email) 45 | case SMS: 46 | fmt.Println("SMS: sent to", user.Mobile) 47 | } 48 | } 49 | 50 | func (notifier emailNotifier) Notify(receiver string,message string) { 51 | fmt.Println(message, " sent to email", receiver) 52 | } 53 | 54 | func (notifier smsNotifier) Notify(receiver string,message string) { 55 | fmt.Println(message, " sent to mobile", receiver) 56 | } 57 | 58 | func NewNotifier(notificationType NotificationType) Notifier { 59 | switch notificationType { 60 | case Email: 61 | return emailNotifier{} 62 | case SMS: 63 | return smsNotifier{} 64 | } 65 | return nil 66 | } -------------------------------------------------------------------------------- /10-Interfaces/06-MiniProject/project1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Bill struct{ 4 | Usage float64 5 | UsageAmount float64 6 | Discount float64 7 | Amount float64 8 | Tax float64 9 | Total float64 10 | } 11 | 12 | func main(){ 13 | 14 | } -------------------------------------------------------------------------------- /11-Modules/01-Module/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/naeemaei/test 2 | 3 | go 1.18 4 | 5 | require github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 // indirect 6 | replace github.com/jalaali/go-jalaali => ./local/go-jalaali -------------------------------------------------------------------------------- /11-Modules/01-Module/go.sum: -------------------------------------------------------------------------------- 1 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE= 2 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE= 3 | -------------------------------------------------------------------------------- /11-Modules/01-Module/local/go-jalaali/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Amir Khazaie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /11-Modules/01-Module/local/go-jalaali/README.md: -------------------------------------------------------------------------------- 1 | # Jalaali 2 | 3 | Golang implementation of [Jalaali JS](https://github.com/jalaali/jalaali-js) and [Jalaali Python](https://github.com/jalaali/jalaali-python) implementations of Jalaali (Jalali, Persian, Khayyami, Khorshidi, Shamsi) convertion to Gregorian calendar system and vice-versa. 4 | 5 | This implementation is based on an [algorithm by Kazimierz M. Borkowski](http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm). Borkowski claims that this algorithm works correctly for 3000 years! 6 | 7 | Documentation on API is available [here](https://pkg.go.dev/github.com/jalaali/go-jalaali) at Go official documentation site. 8 | 9 | ## Installation 10 | 11 | Use `go get` on this repository: 12 | 13 | ```sh 14 | $ go get -u github.com/jalaali/go-jalaali 15 | ``` 16 | 17 | ## Usage 18 | 19 | * Wrapper around Golang [time package](https://golang.org/pkg/time): 20 | * Call `Jalaali.Now()` to get instance of current time. You can use all function from `time` package with this wrapper. 21 | * Call `Jalaali.From(t)` and pass a `time` instance to it. The you can work with it the same way you work with `time` package. 22 | * Jalaali Formatting: 23 | * Call `JFormat` method of a Jalaali instance and pass it the same formatting options that is used for Golang `time` package. The output will be in Jalaali date and use persian digits and words. 24 | -------------------------------------------------------------------------------- /11-Modules/01-Module/local/go-jalaali/errors.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "fmt" 4 | 5 | // ErrorNilReference is happening when a pointer is nil. 6 | type ErrorNilReference struct{} 7 | 8 | // ErrorInvalidYear is happening when year passed is is in proper range. 9 | type ErrorInvalidYear struct { 10 | year int 11 | } 12 | 13 | func (e *ErrorNilReference) Error() string { 14 | return "jalaali: reference is nil" 15 | } 16 | 17 | func (e *ErrorInvalidYear) Error() string { 18 | return fmt.Sprintf("jalaali: %v is invalid year", e.year) 19 | } 20 | -------------------------------------------------------------------------------- /11-Modules/01-Module/local/go-jalaali/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jalaali/go-jalaali 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /11-Modules/01-Module/local/go-jalaali/jalaali.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import ( 4 | "strconv" 5 | "time" 6 | ) 7 | 8 | // A simple wrapper around Golang default time package. You have all the functionality of 9 | // default time package and functionalities needed for Jalaali calender. 10 | type Jalaali struct { 11 | time.Time 12 | } 13 | 14 | // From initialize new instance of Jalaali from a time instance. 15 | func From(t time.Time) Jalaali { 16 | return Jalaali{t} 17 | } 18 | 19 | // Now with return Jalaali instance of current time. 20 | func Now() Jalaali { 21 | return From(time.Now()) 22 | } 23 | 24 | // A Month specifies a month of the year (Farvardin = 1, ...). 25 | type Month int 26 | 27 | const ( 28 | Farvardin Month = 1 + iota 29 | Ordibehesht 30 | Khordad 31 | Tir 32 | Mordad 33 | Shahrivar 34 | Mehr 35 | Aban 36 | Azar 37 | Dey 38 | Bahman 39 | Esfand 40 | ) 41 | 42 | var months = []string{ 43 | "فروردین", "اردیبهشت", "خرداد", 44 | "تیر", "مرداد", "شهریور", 45 | "مهر", "آبان", "آذر", 46 | "دی", "بهمن", "اسفند", 47 | } 48 | 49 | func (m Month) String() string { 50 | if Farvardin <= m && m <= Esfand { 51 | return months[m-1] 52 | } 53 | return "%!Month(" + strconv.Itoa(int(m)) + ")" 54 | } 55 | 56 | // A Weekday specifies a day of the week (Shanbe = 0, ...). 57 | type Weekday int 58 | 59 | const ( 60 | Shanbe Weekday = iota 61 | IekShanbe 62 | DoShanbe 63 | SeShanbe 64 | ChaharShanbe 65 | PanjShanbe 66 | Jome 67 | ) 68 | 69 | var days = []string{ 70 | "شنبه", "یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", 71 | } 72 | 73 | func (d Weekday) String() string { 74 | if Shanbe <= d && d <= Jome { 75 | return days[d] 76 | } 77 | return "%!Weekday(" + strconv.Itoa(int(d)) + ")" 78 | } 79 | 80 | -------------------------------------------------------------------------------- /11-Modules/01-Module/local/go-jalaali/utils.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "strings" 4 | 5 | var enToFa = strings.NewReplacer( 6 | "0", "۰", 7 | "1", "۱", 8 | "2", "۲", 9 | "3", "۳", 10 | "4", "۴", 11 | "5", "۵", 12 | "6", "۶", 13 | "7", "۷", 14 | "8", "۸", 15 | "9", "۹", 16 | ) 17 | 18 | // IsValidDate take Jalaali date and return true if it is valid, 19 | // otherwise false. 20 | func IsValidDate(jy, jm, jd int) bool { 21 | d, err := MonthLength(jy, jm) 22 | if err != nil { 23 | return false 24 | } 25 | return -61 <= jy && jy <= 3177 && 26 | 1 <= jm && jm <= 12 && 27 | 1 <= jd && jd <= d 28 | } 29 | 30 | // MonthLength take Jalaali date and return length of that specific 31 | // month. Error is not nil if Jalaali year passed to function is not valid. 32 | func MonthLength(jy, jm int) (int, error) { 33 | if jm <= 6 { 34 | return 31, nil 35 | } else if jm <= 11 { 36 | return 30, nil 37 | } 38 | 39 | leap, err := IsLeapYear(jy) 40 | if err != nil { 41 | return 0, err 42 | } else if leap { 43 | return 30, nil 44 | } 45 | return 29, nil 46 | } 47 | 48 | // IsLeapYear take a Jalaali year and return true if it is leap year. Error 49 | // is not nil if Jalaali year passed to function is not valid. 50 | func IsLeapYear(jy int) (bool, error) { 51 | leap, _, _, err := jalCal(jy) 52 | return leap == 0, err 53 | } -------------------------------------------------------------------------------- /11-Modules/01-Module/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | jalali "github.com/jalaali/go-jalaali" 5 | ) 6 | 7 | func main() { 8 | x, y, z, _ := jalali.ToGregorian(1396, 2, 2) 9 | 10 | println(x, y, z) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/naeemaei/test 2 | 3 | go 1.18 4 | 5 | require github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 6 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/go.sum: -------------------------------------------------------------------------------- 1 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE= 2 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE= 3 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/go.work: -------------------------------------------------------------------------------- 1 | go 1.18 2 | 3 | use ./local/go-jalaali -------------------------------------------------------------------------------- /11-Modules/02-Workspace/local/go-jalaali/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Amir Khazaie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/local/go-jalaali/README.md: -------------------------------------------------------------------------------- 1 | # Jalaali 2 | 3 | Golang implementation of [Jalaali JS](https://github.com/jalaali/jalaali-js) and [Jalaali Python](https://github.com/jalaali/jalaali-python) implementations of Jalaali (Jalali, Persian, Khayyami, Khorshidi, Shamsi) convertion to Gregorian calendar system and vice-versa. 4 | 5 | This implementation is based on an [algorithm by Kazimierz M. Borkowski](http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm). Borkowski claims that this algorithm works correctly for 3000 years! 6 | 7 | Documentation on API is available [here](https://pkg.go.dev/github.com/jalaali/go-jalaali) at Go official documentation site. 8 | 9 | ## Installation 10 | 11 | Use `go get` on this repository: 12 | 13 | ```sh 14 | $ go get -u github.com/jalaali/go-jalaali 15 | ``` 16 | 17 | ## Usage 18 | 19 | * Wrapper around Golang [time package](https://golang.org/pkg/time): 20 | * Call `Jalaali.Now()` to get instance of current time. You can use all function from `time` package with this wrapper. 21 | * Call `Jalaali.From(t)` and pass a `time` instance to it. The you can work with it the same way you work with `time` package. 22 | * Jalaali Formatting: 23 | * Call `JFormat` method of a Jalaali instance and pass it the same formatting options that is used for Golang `time` package. The output will be in Jalaali date and use persian digits and words. 24 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/local/go-jalaali/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jalaali/go-jalaali 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/local/go-jalaali/jalaali.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import ( 4 | "strconv" 5 | "time" 6 | ) 7 | 8 | // A simple wrapper around Golang default time package. You have all the functionality of 9 | // default time package and functionalities needed for Jalaali calender. 10 | type Jalaali struct { 11 | time.Time 12 | } 13 | 14 | // From initialize new instance of Jalaali from a time instance. 15 | func From(t time.Time) Jalaali { 16 | return Jalaali{t} 17 | } 18 | 19 | // Now with return Jalaali instance of current time. 20 | func Now() Jalaali { 21 | return From(time.Now()) 22 | } 23 | 24 | // A Month specifies a month of the year (Farvardin = 1, ...). 25 | type Month int 26 | 27 | const ( 28 | Farvardin Month = 1 + iota 29 | Ordibehesht 30 | Khordad 31 | Tir 32 | Mordad 33 | Shahrivar 34 | Mehr 35 | Aban 36 | Azar 37 | Dey 38 | Bahman 39 | Esfand 40 | ) 41 | 42 | var months = []string{ 43 | "فروردین", "اردیبهشت", "خرداد", 44 | "تیر", "مرداد", "شهریور", 45 | "مهر", "آبان", "آذر", 46 | "دی", "بهمن", "اسفند", 47 | } 48 | 49 | func (m Month) String() string { 50 | if Farvardin <= m && m <= Esfand { 51 | return months[m-1] 52 | } 53 | return "%!Month(" + strconv.Itoa(int(m)) + ")" 54 | } 55 | 56 | // A Weekday specifies a day of the week (Shanbe = 0, ...). 57 | type Weekday int 58 | 59 | const ( 60 | Shanbe Weekday = iota 61 | IekShanbe 62 | DoShanbe 63 | SeShanbe 64 | ChaharShanbe 65 | PanjShanbe 66 | Jome 67 | ) 68 | 69 | var days = []string{ 70 | "شنبه", "یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", 71 | } 72 | 73 | func (d Weekday) String() string { 74 | if Shanbe <= d && d <= Jome { 75 | return days[d] 76 | } 77 | return "%!Weekday(" + strconv.Itoa(int(d)) + ")" 78 | } 79 | 80 | -------------------------------------------------------------------------------- /11-Modules/02-Workspace/local/go-jalaali/utils.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "strings" 4 | 5 | var enToFa = strings.NewReplacer( 6 | "0", "۰", 7 | "1", "۱", 8 | "2", "۲", 9 | "3", "۳", 10 | "4", "۴", 11 | "5", "۵", 12 | "6", "۶", 13 | "7", "۷", 14 | "8", "۸", 15 | "9", "۹", 16 | ) 17 | 18 | // IsValidDate take Jalaali date and return true if it is valid, 19 | // otherwise false. 20 | func IsValidDate(jy, jm, jd int) bool { 21 | d, err := MonthLength(jy, jm) 22 | if err != nil { 23 | return false 24 | } 25 | return -61 <= jy && jy <= 3177 && 26 | 1 <= jm && jm <= 12 && 27 | 1 <= jd && jd <= d 28 | } 29 | 30 | // MonthLength take Jalaali date and return length of that specific 31 | // month. Error is not nil if Jalaali year passed to function is not valid. 32 | func MonthLength(jy, jm int) (int, error) { 33 | if jm <= 6 { 34 | return 31, nil 35 | } else if jm <= 11 { 36 | return 30, nil 37 | } 38 | 39 | leap, err := IsLeapYear(jy) 40 | if err != nil { 41 | return 0, err 42 | } else if leap { 43 | return 30, nil 44 | } 45 | return 29, nil 46 | } 47 | 48 | // IsLeapYear take a Jalaali year and return true if it is leap year. Error 49 | // is not nil if Jalaali year passed to function is not valid. 50 | func IsLeapYear(jy int) (bool, error) { 51 | leap, _, _, err := jalCal(jy) 52 | return leap == 0, err 53 | } -------------------------------------------------------------------------------- /11-Modules/02-Workspace/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | jalali "github.com/jalaali/go-jalaali" 5 | ) 6 | 7 | func main() { 8 | x, y, z, _ := jalali.ToGregorian(1396, 2, 2) 9 | 10 | println(x, y, z) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/naeemaei/moduleExample 2 | 3 | go 1.18 4 | 5 | require github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 6 | 7 | require github.com/naeemaei/TestModule v0.0.1 // indirect 8 | 9 | replace github.com/jalaali/go-jalaali => ./local/go-jalaali 10 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/go.sum: -------------------------------------------------------------------------------- 1 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE= 2 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE= 3 | github.com/naeemaei/TestModule v0.0.1 h1:EOi7KcM5+hAWfXcbY+MZ4BWDOx3+YGrsVWoXIahpyPc= 4 | github.com/naeemaei/TestModule v0.0.1/go.mod h1:vG6vCeWm8bil8ync2P04+T3S9/e5h1cql6kf8NL1Mbw= 5 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/local/go-jalaali/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Amir Khazaie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/local/go-jalaali/README.md: -------------------------------------------------------------------------------- 1 | # Jalaali 2 | 3 | Golang implementation of [Jalaali JS](https://github.com/jalaali/jalaali-js) and [Jalaali Python](https://github.com/jalaali/jalaali-python) implementations of Jalaali (Jalali, Persian, Khayyami, Khorshidi, Shamsi) convertion to Gregorian calendar system and vice-versa. 4 | 5 | This implementation is based on an [algorithm by Kazimierz M. Borkowski](http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm). Borkowski claims that this algorithm works correctly for 3000 years! 6 | 7 | Documentation on API is available [here](https://pkg.go.dev/github.com/jalaali/go-jalaali) at Go official documentation site. 8 | 9 | ## Installation 10 | 11 | Use `go get` on this repository: 12 | 13 | ```sh 14 | $ go get -u github.com/jalaali/go-jalaali 15 | ``` 16 | 17 | ## Usage 18 | 19 | * Wrapper around Golang [time package](https://golang.org/pkg/time): 20 | * Call `Jalaali.Now()` to get instance of current time. You can use all function from `time` package with this wrapper. 21 | * Call `Jalaali.From(t)` and pass a `time` instance to it. The you can work with it the same way you work with `time` package. 22 | * Jalaali Formatting: 23 | * Call `JFormat` method of a Jalaali instance and pass it the same formatting options that is used for Golang `time` package. The output will be in Jalaali date and use persian digits and words. 24 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/local/go-jalaali/errors.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "fmt" 4 | 5 | // ErrorNilReference is happening when a pointer is nil. 6 | type ErrorNilReference struct{} 7 | 8 | // ErrorInvalidYear is happening when year passed is is in proper range. 9 | type ErrorInvalidYear struct { 10 | year int 11 | } 12 | 13 | func (e *ErrorNilReference) Error() string { 14 | return "jalaali: reference is nil" 15 | } 16 | 17 | func (e *ErrorInvalidYear) Error() string { 18 | return fmt.Sprintf("jalaali: %v is invalid year", e.year) 19 | } 20 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/local/go-jalaali/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jalaali/go-jalaali 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/local/go-jalaali/jalaali.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import ( 4 | "strconv" 5 | "time" 6 | ) 7 | 8 | // A simple wrapper around Golang default time package. You have all the functionality of 9 | // default time package and functionalities needed for Jalaali calender. 10 | type Jalaali struct { 11 | time.Time 12 | } 13 | 14 | // From initialize new instance of Jalaali from a time instance. 15 | func From(t time.Time) Jalaali { 16 | return Jalaali{t} 17 | } 18 | 19 | // Now with return Jalaali instance of current time. 20 | func Now() Jalaali { 21 | return From(time.Now()) 22 | } 23 | 24 | // A Month specifies a month of the year (Farvardin = 1, ...). 25 | type Month int 26 | 27 | const ( 28 | Farvardin Month = 1 + iota 29 | Ordibehesht 30 | Khordad 31 | Tir 32 | Mordad 33 | Shahrivar 34 | Mehr 35 | Aban 36 | Azar 37 | Dey 38 | Bahman 39 | Esfand 40 | ) 41 | 42 | var months = []string{ 43 | "فروردین", "اردیبهشت", "خرداد", 44 | "تیر", "مرداد", "شهریور", 45 | "مهر", "آبان", "آذر", 46 | "دی", "بهمن", "اسفند", 47 | } 48 | 49 | func (m Month) String() string { 50 | if Farvardin <= m && m <= Esfand { 51 | return months[m-1] 52 | } 53 | return "%!Month(" + strconv.Itoa(int(m)) + ")" 54 | } 55 | 56 | // A Weekday specifies a day of the week (Shanbe = 0, ...). 57 | type Weekday int 58 | 59 | const ( 60 | Shanbe Weekday = iota 61 | IekShanbe 62 | DoShanbe 63 | SeShanbe 64 | ChaharShanbe 65 | PanjShanbe 66 | Jome 67 | ) 68 | 69 | var days = []string{ 70 | "شنبه", "یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", 71 | } 72 | 73 | func (d Weekday) String() string { 74 | if Shanbe <= d && d <= Jome { 75 | return days[d] 76 | } 77 | return "%!Weekday(" + strconv.Itoa(int(d)) + ")" 78 | } 79 | 80 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/local/go-jalaali/utils.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "strings" 4 | 5 | var enToFa = strings.NewReplacer( 6 | "0", "۰", 7 | "1", "۱", 8 | "2", "۲", 9 | "3", "۳", 10 | "4", "۴", 11 | "5", "۵", 12 | "6", "۶", 13 | "7", "۷", 14 | "8", "۸", 15 | "9", "۹", 16 | ) 17 | 18 | // IsValidDate take Jalaali date and return true if it is valid, 19 | // otherwise false. 20 | func IsValidDate(jy, jm, jd int) bool { 21 | d, err := MonthLength(jy, jm) 22 | if err != nil { 23 | return false 24 | } 25 | return -61 <= jy && jy <= 3177 && 26 | 1 <= jm && jm <= 12 && 27 | 1 <= jd && jd <= d 28 | } 29 | 30 | // MonthLength take Jalaali date and return length of that specific 31 | // month. Error is not nil if Jalaali year passed to function is not valid. 32 | func MonthLength(jy, jm int) (int, error) { 33 | if jm <= 6 { 34 | return 31, nil 35 | } else if jm <= 11 { 36 | return 30, nil 37 | } 38 | 39 | leap, err := IsLeapYear(jy) 40 | if err != nil { 41 | return 0, err 42 | } else if leap { 43 | return 30, nil 44 | } 45 | return 29, nil 46 | } 47 | 48 | // IsLeapYear take a Jalaali year and return true if it is leap year. Error 49 | // is not nil if Jalaali year passed to function is not valid. 50 | func IsLeapYear(jy int) (bool, error) { 51 | leap, _, _, err := jalCal(jy) 52 | return leap == 0, err 53 | } -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | jalali "github.com/jalaali/go-jalaali" 7 | Math "github.com/naeemaei/TestModule" 8 | "github.com/naeemaei/moduleExample/services" 9 | ) 10 | 11 | func main() { 12 | 13 | fmt.Printf("Hello, world.\n") 14 | 15 | year, month, day, error := jalali.ToGregorian(1401, 5, 34) 16 | if error == nil { 17 | fmt.Printf("%d/%d/%d\n", year, month, day) 18 | } else { 19 | fmt.Printf("%s\n", error) 20 | } 21 | 22 | var service services.TestService = services.TestService{} 23 | var service2 services.TestService2 = services.TestService2{} 24 | 25 | fmt.Printf("%v", service) 26 | fmt.Printf("%v", service2) 27 | 28 | x := Math.Add(1, 2) 29 | y := Math.Subtract(10, 5) 30 | 31 | println(x) 32 | println(y) 33 | } 34 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/services/test2Service.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | type TestService2 struct { 4 | } 5 | -------------------------------------------------------------------------------- /11-Modules/03-ModuleExample/services/testService.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | type TestService struct { 4 | } 5 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/naeemaei/moduleExample 2 | 3 | go 1.18 4 | 5 | require github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 6 | 7 | //replace github.com/jalaali/go-jalaali => ./local/go-jalaali 8 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/go.sum: -------------------------------------------------------------------------------- 1 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE= 2 | github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE= 3 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/go.work: -------------------------------------------------------------------------------- 1 | go 1.18 2 | 3 | use ./local/go-jalaali 4 | use ./ -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/local/go-jalaali/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Amir Khazaie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/local/go-jalaali/README.md: -------------------------------------------------------------------------------- 1 | # Jalaali 2 | 3 | Golang implementation of [Jalaali JS](https://github.com/jalaali/jalaali-js) and [Jalaali Python](https://github.com/jalaali/jalaali-python) implementations of Jalaali (Jalali, Persian, Khayyami, Khorshidi, Shamsi) convertion to Gregorian calendar system and vice-versa. 4 | 5 | This implementation is based on an [algorithm by Kazimierz M. Borkowski](http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm). Borkowski claims that this algorithm works correctly for 3000 years! 6 | 7 | Documentation on API is available [here](https://pkg.go.dev/github.com/jalaali/go-jalaali) at Go official documentation site. 8 | 9 | ## Installation 10 | 11 | Use `go get` on this repository: 12 | 13 | ```sh 14 | $ go get -u github.com/jalaali/go-jalaali 15 | ``` 16 | 17 | ## Usage 18 | 19 | * Wrapper around Golang [time package](https://golang.org/pkg/time): 20 | * Call `Jalaali.Now()` to get instance of current time. You can use all function from `time` package with this wrapper. 21 | * Call `Jalaali.From(t)` and pass a `time` instance to it. The you can work with it the same way you work with `time` package. 22 | * Jalaali Formatting: 23 | * Call `JFormat` method of a Jalaali instance and pass it the same formatting options that is used for Golang `time` package. The output will be in Jalaali date and use persian digits and words. 24 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/local/go-jalaali/errors.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "fmt" 4 | 5 | // ErrorNilReference is happening when a pointer is nil. 6 | type ErrorNilReference struct{} 7 | 8 | // ErrorInvalidYear is happening when year passed is is in proper range. 9 | type ErrorInvalidYear struct { 10 | year int 11 | } 12 | 13 | func (e *ErrorNilReference) Error() string { 14 | return "jalaali: reference is nil" 15 | } 16 | 17 | func (e *ErrorInvalidYear) Error() string { 18 | return fmt.Sprintf("jalaali: %v is invalid year", e.year) 19 | } 20 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/local/go-jalaali/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jalaali/go-jalaali 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/local/go-jalaali/jalaali.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import ( 4 | "strconv" 5 | "time" 6 | ) 7 | 8 | // A simple wrapper around Golang default time package. You have all the functionality of 9 | // default time package and functionalities needed for Jalaali calender. 10 | type Jalaali struct { 11 | time.Time 12 | } 13 | 14 | // From initialize new instance of Jalaali from a time instance. 15 | func From(t time.Time) Jalaali { 16 | return Jalaali{t} 17 | } 18 | 19 | // Now with return Jalaali instance of current time. 20 | func Now() Jalaali { 21 | return From(time.Now()) 22 | } 23 | 24 | // A Month specifies a month of the year (Farvardin = 1, ...). 25 | type Month int 26 | 27 | const ( 28 | Farvardin Month = 1 + iota 29 | Ordibehesht 30 | Khordad 31 | Tir 32 | Mordad 33 | Shahrivar 34 | Mehr 35 | Aban 36 | Azar 37 | Dey 38 | Bahman 39 | Esfand 40 | ) 41 | 42 | var months = []string{ 43 | "فروردین", "اردیبهشت", "خرداد", 44 | "تیر", "مرداد", "شهریور", 45 | "مهر", "آبان", "آذر", 46 | "دی", "بهمن", "اسفند", 47 | } 48 | 49 | func (m Month) String() string { 50 | if Farvardin <= m && m <= Esfand { 51 | return months[m-1] 52 | } 53 | return "%!Month(" + strconv.Itoa(int(m)) + ")" 54 | } 55 | 56 | // A Weekday specifies a day of the week (Shanbe = 0, ...). 57 | type Weekday int 58 | 59 | const ( 60 | Shanbe Weekday = iota 61 | IekShanbe 62 | DoShanbe 63 | SeShanbe 64 | ChaharShanbe 65 | PanjShanbe 66 | Jome 67 | ) 68 | 69 | var days = []string{ 70 | "شنبه", "یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", 71 | } 72 | 73 | func (d Weekday) String() string { 74 | if Shanbe <= d && d <= Jome { 75 | return days[d] 76 | } 77 | return "%!Weekday(" + strconv.Itoa(int(d)) + ")" 78 | } 79 | 80 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/local/go-jalaali/utils.go: -------------------------------------------------------------------------------- 1 | package jalaali 2 | 3 | import "strings" 4 | 5 | var enToFa = strings.NewReplacer( 6 | "0", "۰", 7 | "1", "۱", 8 | "2", "۲", 9 | "3", "۳", 10 | "4", "۴", 11 | "5", "۵", 12 | "6", "۶", 13 | "7", "۷", 14 | "8", "۸", 15 | "9", "۹", 16 | ) 17 | 18 | // IsValidDate take Jalaali date and return true if it is valid, 19 | // otherwise false. 20 | func IsValidDate(jy, jm, jd int) bool { 21 | d, err := MonthLength(jy, jm) 22 | if err != nil { 23 | return false 24 | } 25 | return -61 <= jy && jy <= 3177 && 26 | 1 <= jm && jm <= 12 && 27 | 1 <= jd && jd <= d 28 | } 29 | 30 | // MonthLength take Jalaali date and return length of that specific 31 | // month. Error is not nil if Jalaali year passed to function is not valid. 32 | func MonthLength(jy, jm int) (int, error) { 33 | if jm <= 6 { 34 | return 31, nil 35 | } else if jm <= 11 { 36 | return 30, nil 37 | } 38 | 39 | leap, err := IsLeapYear(jy) 40 | if err != nil { 41 | return 0, err 42 | } else if leap { 43 | return 30, nil 44 | } 45 | return 29, nil 46 | } 47 | 48 | // IsLeapYear take a Jalaali year and return true if it is leap year. Error 49 | // is not nil if Jalaali year passed to function is not valid. 50 | func IsLeapYear(jy int) (bool, error) { 51 | leap, _, _, err := jalCal(jy) 52 | return leap == 0, err 53 | } -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | jalali "github.com/jalaali/go-jalaali" 7 | "github.com/naeemaei/moduleExample/services" 8 | ) 9 | 10 | func main() { 11 | 12 | fmt.Printf("Hello, world.\n") 13 | 14 | year, month, day, error := jalali.ToGregorian(1401, 15, 1) 15 | if error == nil { 16 | fmt.Printf("%d/%d/%d\n", year, month, day) 17 | } else { 18 | fmt.Printf("%s\n", error) 19 | } 20 | 21 | var service services.TestService = services.TestService{} 22 | var service2 services.TestService2 = services.TestService2{} 23 | 24 | fmt.Printf("%v", service) 25 | fmt.Printf("%v", service2) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/services/test2Service.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | type TestService2 struct { 4 | } 5 | -------------------------------------------------------------------------------- /11-Modules/03-WorkspaceExample/services/testService.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | type TestService struct { 4 | } 5 | -------------------------------------------------------------------------------- /12-Generics/02-Examples/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Number interface{ 6 | int | int16 | int32 | int64 | float32 | float64 7 | } 8 | 9 | func main() { 10 | x := Sum(2, 7) 11 | fmt.Printf("%d\n", x) 12 | 13 | y := Sum(2.5, 7.5) 14 | fmt.Printf("%f\n", y) 15 | } 16 | 17 | func SumInts(a, b int) int { 18 | return a + b 19 | } 20 | 21 | func SumFloats(a, b float64) float64 { 22 | return a + b 23 | } 24 | 25 | func Sum[T Number](a, b T) T { 26 | return a + b 27 | } 28 | 29 | 30 | // func Call[Input any, Output any](headers string, uri string, input Input) Output { 31 | // // http request() 32 | // // 33 | 34 | // } 35 | -------------------------------------------------------------------------------- /12-Generics/02-Examples/example2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Number interface { 6 | int | float64 7 | } 8 | 9 | func main() { 10 | 11 | mySlice := []int{1, 2, 3, 4, 5} 12 | 13 | fmt.Printf("%d\n", Sum(mySlice)) 14 | 15 | mySlice2 := []float64{1.5, 2.5, 3.5, 4.5, 5.5} 16 | 17 | fmt.Printf("%f\n", Sum(mySlice2)) 18 | } 19 | 20 | func Sum[T Number](slc []T) (sum T) { 21 | for _, v := range slc { 22 | sum += v 23 | } 24 | return 25 | } 26 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/01-List/generics/list.go: -------------------------------------------------------------------------------- 1 | package generics 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/google/go-cmp/cmp" 7 | ) 8 | 9 | type List[T any] struct { 10 | Items []T 11 | } 12 | 13 | func (list *List[T]) Add(item T) { 14 | list.Items = append(list.Items, item) 15 | } 16 | 17 | func (list *List[T]) InsertAt(index int, item T) { 18 | // 1 2 3 4 5 19 | // 1 2 30 3 4 5 20 | list.Items = append(list.Items, item) // 1 2 3 4 5 30 21 | copy(list.Items[index+1:], list.Items[index:]) // 1 2 3 3 4 5 22 | list.Items[index] = item // 1 2 30 3 4 5 23 | 24 | } 25 | 26 | func (list *List[T]) RemoveAt(index int) { 27 | // 1 2 3 4 5 6 7 8 9 10 28 | defer func() { 29 | if err := recover(); err != nil { 30 | fmt.Println(err) 31 | } 32 | }() 33 | list.Items = append(list.Items[:index*-1], list.Items[index+1:]...) 34 | } 35 | func (list *List[T]) Remove(item T) { 36 | index := list.Find(item) 37 | if index != -1 { 38 | list.RemoveAt(index) 39 | } 40 | } 41 | 42 | func (list *List[T]) Get(index int) T { 43 | return list.Items[index] 44 | } 45 | 46 | func (list *List[T]) Find(item T) int { 47 | for i, v := range list.Items { 48 | if cmp.Equal(v, item) { 49 | return i 50 | } 51 | } 52 | return -1 53 | } 54 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/01-List/go.mod: -------------------------------------------------------------------------------- 1 | module genericList 2 | 3 | go 1.18 4 | 5 | require github.com/google/go-cmp v0.5.8 // indirect 6 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/01-List/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= 2 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/01-List/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "genericList/generics" 6 | ) 7 | 8 | type Person struct { 9 | Name string 10 | Age int 11 | } 12 | 13 | func main() { 14 | 15 | genericInt() 16 | genericString() 17 | genericPerson() 18 | } 19 | 20 | func genericInt() { 21 | list1 := generics.List[int]{Items: []int{}} 22 | 23 | list1.Add(10) 24 | list1.Add(20) 25 | list1.Add(30) 26 | fmt.Printf("%v\n", list1.Items) 27 | 28 | list1.InsertAt(1, 15) 29 | fmt.Printf("%v\n", list1.Items) 30 | 31 | list1.RemoveAt(2) 32 | fmt.Printf("%v\n", list1.Items) 33 | 34 | list1.Remove(30) 35 | fmt.Printf("%v\n", list1.Items) 36 | } 37 | 38 | func genericString() { 39 | list1 := generics.List[string]{Items: []string{}} 40 | 41 | list1.Add("Ali") 42 | list1.Add("Reza") 43 | list1.Add("Milad") 44 | fmt.Printf("%v\n", list1.Items) 45 | 46 | list1.Remove("Reza") 47 | fmt.Printf("%v\n", list1.Items) 48 | 49 | list1.InsertAt(1, "Reza1") 50 | fmt.Printf("%v\n", list1.Items) 51 | 52 | } 53 | func genericPerson() { 54 | list1 := generics.List[Person]{Items: []Person{}} 55 | list1.Add(Person{Name: "Ali", Age: 30}) 56 | list1.Add(Person{Name: "Reza", Age: 20}) 57 | list1.Add(Person{Name: "Milad", Age: 10}) 58 | 59 | fmt.Printf("%v\n", list1.Items) 60 | 61 | list1.Remove(Person{Name: "Reza", Age: 20}) 62 | fmt.Printf("%v\n", list1.Items) 63 | 64 | list1.InsertAt(1, Person{Name: "Reza1", Age: 20}) 65 | fmt.Printf("%v\n", list1.Items) 66 | 67 | } 68 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/02-List/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Package", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/02-List/go.mod: -------------------------------------------------------------------------------- 1 | module miniProject 2 | 3 | go 1.18 4 | 5 | require github.com/google/go-cmp v0.5.8 // indirect 6 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/02-List/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= 2 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | -------------------------------------------------------------------------------- /12-Generics/03-MiniProject/02-List/project.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/google/go-cmp/cmp" 7 | ) 8 | 9 | type List[T any] struct { 10 | Items []T 11 | } 12 | 13 | type Person struct { 14 | Name string 15 | Age int 16 | } 17 | 18 | func main() { 19 | 20 | lst := List[int]{Items: []int{}} 21 | lst.Add(2) 22 | lst.Add(10) 23 | lst.Add(11) 24 | lst.Add(12) 25 | lst.Add(13) 26 | lst.Add(14) 27 | 28 | fmt.Printf("%+v\n", lst.Items) 29 | 30 | lst.InsertAt(4, 20) 31 | lst.InsertAt(5, 30) 32 | lst.InsertAt(1, 40) 33 | 34 | fmt.Printf("%+v\n", lst.Items) 35 | 36 | lst1 := List[Person]{Items: []Person{}} 37 | 38 | lst1.Add(Person{Name: "John", Age: 30}) 39 | lst1.Add(Person{Name: "Jane", Age: 25}) 40 | lst1.Add(Person{Name: "Jack", Age: 27}) 41 | lst1.Add(Person{Name: "Jill", Age: 22}) 42 | lst1.Add(Person{Name: "Joe", Age: 28}) 43 | lst1.Add(Person{Name: "Jill", Age: 22}) 44 | lst1.Add(Person{Name: "Joe", Age: 28}) 45 | 46 | lst1.InsertAt(4, Person{Name: "Hamed", Age: 30}) 47 | 48 | lst1.RemoveAt(3) 49 | 50 | fmt.Printf("%+v\n", lst1.Items) 51 | 52 | } 53 | 54 | func (list *List[T]) Add(item T) { 55 | list.Items = append(list.Items, item) 56 | } 57 | 58 | func (list *List[T]) Remove(item T) { 59 | index := list.Find(item) 60 | list.RemoveAt(index) 61 | } 62 | 63 | func (list *List[T]) RemoveAt(index int) { 64 | list.Items = append(list.Items[:index*2], (list.Items[index+1:])...) 65 | } 66 | 67 | func (list *List[T]) InsertAt(index int, item T) { 68 | list.Items = append(list.Items, item) 69 | copy(list.Items[index+1:], list.Items[index:]) 70 | list.Items[index] = item 71 | } 72 | 73 | func (list *List[T]) Find(item T) (index int) { 74 | 75 | for i, v := range list.Items { 76 | if cmp.Equal(v, item) { 77 | index = i 78 | return 79 | } 80 | } 81 | return -1 82 | } 83 | -------------------------------------------------------------------------------- /13-Errors/02-Error/17162-7Learn/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Package", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}/main.go" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /13-Errors/02-Error/17162-7Learn/go.mod: -------------------------------------------------------------------------------- 1 | module ErrorExample 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /13-Errors/02-Error/17162-7Learn/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | type IOError struct { 11 | FileName string 12 | Message string 13 | Err error 14 | } 15 | 16 | func (error *IOError) Unwrap() error { 17 | return error.Err 18 | } 19 | 20 | func (error IOError) Error() string { 21 | return fmt.Sprintf("IO error occurred: FileName: %s Message: %s Detail: %s", error.FileName, error.Message, error.Err.Error()) 22 | } 23 | 24 | func CopyFile(srcName, dstName string) error { 25 | src, err := os.Open(srcName) 26 | if err != nil { 27 | return &IOError{FileName: srcName, Message: "during copy file could not open source file", Err: err} 28 | } 29 | //defer src.Close() 30 | dst, err := os.Create(dstName) 31 | if err != nil { 32 | return &IOError{FileName: srcName, Message: "during copy file could not create destination file", Err: err} 33 | } 34 | dst.Close() 35 | _, err = io.Copy(dst, src) 36 | fmt.Printf("io error: %s\n", err) 37 | var ioErr IOError = IOError{} 38 | if errors.Is(err,ioErr){ 39 | fmt.Printf("cast error: %s\n", ioErr) 40 | } 41 | if err != nil { 42 | return &IOError{FileName: srcName, Message: "during copy file could not copy", Err: err} 43 | } 44 | return nil 45 | } 46 | func main() { 47 | err := CopyFile("src.txt", "dst.txt") 48 | fmt.Printf("%s\n", err) 49 | fmt.Printf("Unwrap Error: %s", errors.Unwrap(err)) 50 | 51 | if err != nil { 52 | fmt.Printf("Error: %s\n", err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /13-Errors/02-Error/createError.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | output, err := createErrorMethod2(0) 10 | if err != nil { 11 | fmt.Println(err) 12 | return 13 | } 14 | fmt.Println(output) 15 | 16 | } 17 | 18 | func createErrorMethod1(number int) (int, error) { 19 | if number == 0 { 20 | return 0, errors.New("Number is not valid") 21 | } 22 | return number * 5, nil 23 | } 24 | 25 | func createErrorMethod2(number int) (int, error) { 26 | if number == 0 { 27 | return 0, fmt.Errorf("Number is not valid: %d", number) 28 | } 29 | return number * 5, nil 30 | } 31 | -------------------------------------------------------------------------------- /13-Errors/02-Error/customError.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | ) 8 | 9 | type HttpError struct { 10 | StatusCode int 11 | Message string 12 | } 13 | 14 | func main() { 15 | 16 | response, err := GetRequest("") 17 | if err != nil { 18 | fmt.Println(err) 19 | return 20 | } 21 | 22 | fmt.Println(response) 23 | 24 | } 25 | 26 | func (error HttpError) Error() string { 27 | return fmt.Sprintf("Http error occurred: %d %s", error.StatusCode, error.Message) 28 | } 29 | 30 | func NewHttpError(statusCode int, message string) *HttpError { 31 | return &HttpError{StatusCode: statusCode, Message: message} 32 | } 33 | 34 | func GetRequest(url string) (string, error) { 35 | if len(url) == 0 { 36 | return "", NewHttpError(400, "Url is empty") 37 | } 38 | response, err := http.Get(url) 39 | if err != nil { 40 | return "", NewHttpError(500, "Error occurred") 41 | } 42 | 43 | responseBody, err := ioutil.ReadAll(response.Body) 44 | 45 | if err != nil { 46 | return "", NewHttpError(200, "Body is empty") 47 | } 48 | return string(responseBody), nil 49 | } 50 | -------------------------------------------------------------------------------- /13-Errors/02-Error/error1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | 10 | response, err := http.Get("https://dummyjson3123.com/products/categories") 11 | 12 | if err != nil { 13 | println("an error has occurred on get request") 14 | return 15 | } 16 | 17 | println(response.Status) 18 | 19 | responseBody, err := ioutil.ReadAll(response.Body) 20 | 21 | if err != nil { 22 | println("an error has occurred on reading the response body") 23 | } 24 | 25 | println(string(responseBody)) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /13-Errors/03-Wrapping/dest.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naeemaei/Golang-Tutorial/a5e0b8af03294841921740f8925fbd107cda8182/13-Errors/03-Wrapping/dest.txt -------------------------------------------------------------------------------- /13-Errors/03-Wrapping/method1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | err := CopyFile("src.txt", "dest.txt") 11 | if err != nil { 12 | fmt.Printf("Error: %s\n", err) 13 | } 14 | } 15 | 16 | func CopyFile(sourceName, destinationName string) error { 17 | 18 | source, err := os.Open(sourceName) 19 | 20 | if err != nil { 21 | return fmt.Errorf("during copy file could not open source file: %w", err) 22 | } 23 | 24 | /*defer*/ source.Close() 25 | 26 | destination, err := os.Create(destinationName) 27 | 28 | if err != nil { 29 | return fmt.Errorf("during copy file could not create destination file: %w", err) 30 | } 31 | 32 | defer destination.Close() 33 | 34 | _, err = io.Copy(destination, source) 35 | 36 | if err != nil { 37 | return fmt.Errorf("during copy file could not copy: %w", err) 38 | } 39 | //defer destination.Close() 40 | 41 | return nil 42 | 43 | } 44 | -------------------------------------------------------------------------------- /13-Errors/03-Wrapping/method2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | type IOError struct { 11 | FileName string 12 | Message string 13 | Err error 14 | } 15 | 16 | func (error *IOError) Unwrap() error { 17 | return error.Err 18 | } 19 | 20 | func (error IOError) Error() string { 21 | return fmt.Sprintf("IO error occurred: FileName: %s Message: %s Detail: %s", error.FileName, error.Message, error.Err.Error()) 22 | } 23 | 24 | func main() { 25 | err := CopyFile("src.txt", "dest.txt") 26 | if err != nil { 27 | fmt.Printf("Error: %s\n", err) 28 | fmt.Printf("Unwrapped error: %s\n", errors.Unwrap(err)) 29 | } 30 | } 31 | 32 | func CopyFile(sourceName, destinationName string) error { 33 | 34 | source, err := os.Open(sourceName) 35 | 36 | if err != nil { 37 | return &IOError{FileName: sourceName, Message: "during copy file could not open source file", Err: err} 38 | } 39 | 40 | /*defer*/ 41 | source.Close() 42 | 43 | destination, err := os.Create(destinationName) 44 | 45 | if err != nil { 46 | return &IOError{FileName: sourceName, Message: "during copy file could not create destination file", Err: err} 47 | } 48 | 49 | defer destination.Close() 50 | 51 | _, err = io.Copy(destination, source) 52 | 53 | if err != nil { 54 | return &IOError{FileName: sourceName, Message: "during copy file could not copy file", Err: err} 55 | } 56 | //defer destination.Close() 57 | 58 | return nil 59 | 60 | } 61 | -------------------------------------------------------------------------------- /13-Errors/03-Wrapping/src1.txt: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /13-Errors/Panic/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime/debug" 6 | ) 7 | 8 | func main() { 9 | GetEmployeeInfo("ali", "alavi", 1000000) 10 | 11 | fmt.Println("end of main") 12 | } 13 | 14 | func GetEmployeeInfo(firstName, lastName string, salary int) float64 { 15 | defer func() { 16 | if err := recover(); err != nil { 17 | fmt.Println("Error: ", err) 18 | fmt.Println("Recovering from error...") 19 | debug.PrintStack() 20 | } 21 | }() 22 | if firstName == "" { 23 | panic("First name is empty") 24 | } 25 | 26 | fmt.Printf("First name: %s\n", firstName) 27 | 28 | if lastName == "" { 29 | panic("Last name is empty") 30 | } 31 | 32 | fmt.Printf("Last name: %s\n", lastName) 33 | 34 | if salary <= 0 { 35 | panic("Salary is less than 0") 36 | } 37 | 38 | fmt.Printf("Salary: %d\n", salary) 39 | 40 | return CalculateTax(salary) 41 | } 42 | 43 | func CalculateTax(salary int) float64 { 44 | tax := float64(salary) * 0.09 45 | if tax > 1000 { 46 | panic("Tax is greater than 1000") 47 | } 48 | fmt.Printf("Tax: %f\n", tax) 49 | return tax 50 | } 51 | -------------------------------------------------------------------------------- /13-Errors/Panic/test1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime/debug" 6 | ) 7 | 8 | func main() { 9 | defer func() { 10 | fmt.Println("Start of Defer main") 11 | if err := recover(); err != nil { 12 | fmt.Println("Error: ", err) 13 | fmt.Println("Recovering from error...") 14 | debug.PrintStack() 15 | } 16 | }() 17 | nums := []int{1, 2, 3, 4, 5} 18 | function1(nums, 6) 19 | 20 | Divide(10, 2) 21 | 22 | Divide(10, 0) 23 | } 24 | 25 | func function1(numbers []int, index int) { 26 | defer func() { 27 | fmt.Println("Start of Defer function1") 28 | }() 29 | // 1 - index out of range 30 | //fmt.Println(numbers[index]) 31 | // 2 - panic 32 | //panic("panic") 33 | // 3 - log 34 | //log.Fatal("Fatal") 35 | //fmt.Println(12) 36 | } 37 | 38 | func Divide(a, b int) { 39 | defer func() { 40 | fmt.Println("Defer of divide") 41 | }() 42 | fmt.Printf("Start of divide: %d , %d\n", a, b) 43 | fmt.Printf("Result: %d\n", a/b) 44 | fmt.Printf("End of divide: %d , %d\n", a, b) 45 | 46 | } 47 | -------------------------------------------------------------------------------- /14-Logging/02-LogLibrary/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | ) 7 | 8 | var ( 9 | errorLogger *log.Logger 10 | warnLogger *log.Logger 11 | infoLogger *log.Logger 12 | ) 13 | 14 | func init() { 15 | file, err := os.OpenFile("log.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666) 16 | if err != nil { 17 | log.Fatalln("Failed to open log file", err) 18 | } 19 | flags := log.Ldate | log.Ltime | log.Lshortfile 20 | 21 | log.SetFlags(flags) 22 | 23 | log.SetOutput(file) 24 | 25 | errorLogger = log.New(file, "Error: ", flags) 26 | warnLogger = log.New(file, "Warn: ", flags) 27 | infoLogger = log.New(file, "Info: ", flags) 28 | } 29 | func main() { 30 | infoLogger.Println("Start of main") 31 | 32 | Sum(1, 5) 33 | } 34 | 35 | func Sum(a, b int) { 36 | warnLogger.Println("Start of Sum") 37 | println(a + b) 38 | warnLogger.Println("End of Sum") 39 | } 40 | -------------------------------------------------------------------------------- /14-Logging/02-LogLibrary/log.txt: -------------------------------------------------------------------------------- 1 | 2022/07/29 13:26:48 Start of main 2 | 2022/07/29 13:26:48 Start of Sum 3 | 2022/07/29 13:26:48 End of Sum 4 | 2022/07/29 13:27:01 Start of main 5 | 2022/07/29 13:27:01 Start of Sum 6 | 2022/07/29 13:27:01 End of Sum 7 | 2022/07/29 13:29:20 example1.go:18: Start of main 8 | 2022/07/29 13:29:20 example1.go:24: Start of Sum 9 | 2022/07/29 13:29:20 example1.go:26: End of Sum 10 | 2022/07/29 example1.go:18: Start of main 11 | 2022/07/29 example1.go:24: Start of Sum 12 | 2022/07/29 example1.go:26: End of Sum 13 | Info: 2022/07/29 13:33:47 example1.go:30: Start of main 14 | Warn: 2022/07/29 13:33:47 example1.go:36: Start of Sum 15 | Warn: 2022/07/29 13:33:47 example1.go:38: End of Sum 16 | {"time": "2022/07/29 13:33:47", "level": "Info", "msg": "Start of main"} 17 | {"time": "2022/07/29 13:33:47", "level": "Warn", "msg": "Start of Sum"} 18 | {"time": "2022/07/29 13:33:47", "level": "Warn", "msg": "End of Sum"} 19 | {"time": "2022/07/29 13:33:47", "level": "Info", "msg": "End of main"} 20 | -------------------------------------------------------------------------------- /14-Logging/03-LogToFile/core/logger.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/rs/zerolog" 8 | "github.com/rs/zerolog/pkgerrors" 9 | ) 10 | 11 | func NewFileLogger() *zerolog.Logger { 12 | zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack 13 | zerolog.SetGlobalLevel(zerolog.InfoLevel) 14 | 15 | file, err := os.OpenFile("log.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666) 16 | 17 | if err != nil { 18 | log.Println("Failed to open log file:", err) 19 | } 20 | 21 | logger := zerolog.New(file). 22 | With(). 23 | Timestamp(). 24 | Str("AppName", "MyApp"). 25 | Logger() 26 | 27 | return &logger 28 | } 29 | -------------------------------------------------------------------------------- /14-Logging/03-LogToFile/go.mod: -------------------------------------------------------------------------------- 1 | module logToFile 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/pkg/errors v0.9.1 7 | github.com/rs/zerolog v1.27.0 8 | ) 9 | 10 | require ( 11 | github.com/mattn/go-colorable v0.1.12 // indirect 12 | github.com/mattn/go-isatty v0.0.14 // indirect 13 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /14-Logging/03-LogToFile/go.sum: -------------------------------------------------------------------------------- 1 | github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 2 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 3 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 4 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 5 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 6 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 7 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 8 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 9 | github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 10 | github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= 11 | github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= 12 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 14 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= 15 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 16 | -------------------------------------------------------------------------------- /14-Logging/03-LogToFile/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "logToFile/core" 5 | 6 | "github.com/pkg/errors" 7 | ) 8 | 9 | type myStruct struct { 10 | Name string 11 | } 12 | 13 | var logger = core.NewFileLogger() 14 | 15 | func main() { 16 | 17 | logger.Print("test") 18 | myStruct := myStruct{Name: "test"} 19 | logger.Info().Interface("Body", myStruct).Str("Category", "Search"). 20 | Int("DurationTime", 80). 21 | Msg("Searching for a thing") 22 | 23 | err := errors.New("this is an error") 24 | 25 | logger.Error().Err(err).Msg("Error occurred") 26 | 27 | err = func3() 28 | if err != nil { 29 | 30 | logger.Error().Stack().Err(err).Msg("Error occurred (func3 error)") 31 | } 32 | } 33 | 34 | func func1() error { 35 | return errors.New("this is an error (func1)") 36 | } 37 | 38 | func func2() error { 39 | err := func1() 40 | if err != nil { 41 | return err 42 | } 43 | return nil 44 | } 45 | 46 | func func3() error { 47 | err := func2() 48 | if err != nil { 49 | return err 50 | } 51 | return nil 52 | } 53 | 54 | // trace 55 | // debug 56 | // info 57 | // warn 58 | // error 59 | // fatal(critical) 60 | // panic 61 | -------------------------------------------------------------------------------- /14-Logging/03-LoggingWithThirdParty/go.mod: -------------------------------------------------------------------------------- 1 | module loggingExample 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/mattn/go-colorable v0.1.12 // indirect 7 | github.com/mattn/go-isatty v0.0.14 // indirect 8 | github.com/pkg/errors v0.9.1 // indirect 9 | github.com/rs/zerolog v1.27.0 // indirect 10 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /14-Logging/03-LoggingWithThirdParty/go.sum: -------------------------------------------------------------------------------- 1 | github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 2 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 3 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 4 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 5 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 6 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 7 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 8 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 9 | github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 10 | github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= 11 | github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= 12 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 14 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= 15 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 16 | -------------------------------------------------------------------------------- /14-Logging/03-LoggingWithThirdParty/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | 6 | "github.com/rs/zerolog" 7 | "github.com/rs/zerolog/log" 8 | "github.com/rs/zerolog/pkgerrors" 9 | ) 10 | 11 | func main() { 12 | 13 | //zerolog.TimeFieldFormat = zerolog.TimeFormatUnix 14 | zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack 15 | zerolog.SetGlobalLevel(zerolog.InfoLevel) 16 | log.Print("test") 17 | 18 | log.Info() 19 | .Str("Category", "Search") 20 | .Int("DurationTime", 80) 21 | .Msg("Searching for a thing") 22 | 23 | err := errors.New("this is an error") 24 | 25 | log.Error().Err(err).Msg("Error occurred") 26 | 27 | err = func3() 28 | if err != nil { 29 | log.Error().Stack().Err(err).Msg("Error occurred (func3 error)") 30 | } 31 | } 32 | 33 | func func1() error { 34 | return errors.New("this is an error (func1)") 35 | } 36 | 37 | func func2() error { 38 | err := func1() 39 | if err != nil { 40 | return err 41 | } 42 | return nil 43 | } 44 | 45 | func func3() error { 46 | err := func2() 47 | if err != nil { 48 | return err 49 | } 50 | return nil 51 | } 52 | 53 | // trace 54 | // debug 55 | // info 56 | // warn 57 | // error 58 | // fatal(critical) 59 | // panic 60 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/core/logger.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/rs/zerolog" 8 | "github.com/rs/zerolog/pkgerrors" 9 | ) 10 | 11 | func NewFileLogger() *zerolog.Logger { 12 | zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack 13 | zerolog.SetGlobalLevel(zerolog.InfoLevel) 14 | 15 | file, err := os.OpenFile("log.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666) 16 | 17 | if err != nil { 18 | log.Println("Failed to open log file:", err) 19 | } 20 | 21 | logger := zerolog.New(file). 22 | With(). 23 | Timestamp(). 24 | Str("AppName", "MyApp"). 25 | Logger() 26 | 27 | return &logger 28 | } 29 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/entities/notificationType.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | type NotificationType string 4 | 5 | const ( 6 | Email NotificationType = "Email" 7 | Sms NotificationType = "Sms" 8 | ) 9 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/entities/order.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | type Order struct { 4 | ID int64 5 | UserFullName string 6 | UserId string 7 | Price float64 8 | Status bool 9 | NotificationType NotificationType 10 | } 11 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/externalServices/emailService.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import ( 4 | "fmt" 5 | "notification/core" 6 | "notification/entities" 7 | 8 | "github.com/rs/zerolog" 9 | ) 10 | 11 | var logger = core.NewFileLogger() 12 | 13 | type EmailService struct { 14 | } 15 | 16 | func (e *EmailService) SendMessage(order *entities.Order) { 17 | fmt.Printf("Email sent: %v\n", order) 18 | } 19 | 20 | func (e *EmailService) SendNotify(receiver string, message string) error { 21 | if receiver == "" { 22 | return fmt.Errorf("receiver is empty") 23 | } 24 | 25 | fmt.Printf("Email sent: receiver: %s, message: %s\n", receiver, message) 26 | 27 | fmt.Printf("nilNotifyService: receiver: %s, message: %s\n", receiver, message) 28 | logger.Info().Str("notifier", "nilNotifyService"). 29 | Dict("messageInfo", zerolog.Dict(). 30 | Str("receiver", receiver).Str("message", message)). 31 | Msg("Message sent") 32 | 33 | return nil 34 | } 35 | 36 | func NewEmailService() *EmailService { 37 | return &EmailService{} 38 | } 39 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/externalServices/nilNotifyService.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/rs/zerolog" 7 | ) 8 | 9 | type NilNotifyService struct { 10 | } 11 | 12 | func (e *NilNotifyService) SendNotify(receiver string, message string) error { 13 | if receiver == "" { 14 | return fmt.Errorf("receiver is empty") 15 | } 16 | fmt.Printf("nilNotifyService: receiver: %s, message: %s\n", receiver, message) 17 | logger.Info().Str("notifier", "nilNotifyService"). 18 | Dict("messageInfo", zerolog.Dict(). 19 | Str("receiver", receiver).Str("message", message)). 20 | Msg("Message sent") 21 | 22 | return nil 23 | } 24 | 25 | func NewNilNotifyService() *NilNotifyService { 26 | return &NilNotifyService{} 27 | } 28 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/externalServices/notifier.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import "notification/entities" 4 | 5 | type Notifier interface { 6 | SendNotify(receiver string, message string) error 7 | } 8 | 9 | func NewNotifier(notificationType entities.NotificationType) Notifier { 10 | switch notificationType { 11 | case entities.Sms: 12 | return NewSmsService() 13 | case entities.Email: 14 | return NewEmailService() 15 | default: 16 | return NewNilNotifyService() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/externalServices/smsService.go: -------------------------------------------------------------------------------- 1 | package externalServices 2 | 3 | import ( 4 | "fmt" 5 | "notification/entities" 6 | 7 | "github.com/rs/zerolog" 8 | ) 9 | 10 | type SmsService struct { 11 | } 12 | 13 | func (e *SmsService) SendMessage(order *entities.Order) { 14 | fmt.Printf("sms sent: %v\n", order) 15 | } 16 | 17 | func (e *SmsService) SendNotify(receiver string, message string) error { 18 | if receiver == "" { 19 | return fmt.Errorf("receiver is empty") 20 | } 21 | 22 | fmt.Printf("sms sent: receiver: %s, message: %s\n", receiver, message) 23 | 24 | fmt.Printf("nilNotifyService: receiver: %s, message: %s\n", receiver, message) 25 | logger.Info().Str("notifier", "nilNotifyService"). 26 | Dict("messageInfo", zerolog.Dict(). 27 | Str("receiver", receiver).Str("message", message)). 28 | Msg("Message sent") 29 | 30 | return nil 31 | } 32 | 33 | func NewSmsService() *SmsService { 34 | return &SmsService{} 35 | } 36 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/go.mod: -------------------------------------------------------------------------------- 1 | module notification 2 | 3 | go 1.18 4 | 5 | require github.com/rs/zerolog v1.27.0 6 | 7 | require ( 8 | github.com/mattn/go-colorable v0.1.12 // indirect 9 | github.com/mattn/go-isatty v0.0.14 // indirect 10 | github.com/pkg/errors v0.9.1 // indirect 11 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/go.sum: -------------------------------------------------------------------------------- 1 | github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 2 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 3 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 4 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 5 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 6 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 7 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 8 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 9 | github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 10 | github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= 11 | github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= 12 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 14 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= 15 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 16 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/main.go: -------------------------------------------------------------------------------- 1 | // main -> orderService -> emailService || smsService 2 | package main 3 | 4 | import ( 5 | "log" 6 | "notification/core" 7 | "notification/entities" 8 | "notification/services" 9 | ) 10 | 11 | var logger = core.NewFileLogger() 12 | 13 | func main() { 14 | log.Logger = logger 15 | order1 := entities.Order{ 16 | ID: 1, 17 | UserFullName: "John Doe", 18 | UserId: "09115252524", 19 | Price: float64(100), 20 | Status: true, 21 | NotificationType: entities.Email, 22 | } 23 | order2 := entities.Order{ 24 | ID: 2, 25 | UserFullName: "John Mac", 26 | UserId: "09123332221", 27 | Price: float64(220), 28 | Status: true, 29 | NotificationType: entities.Sms, 30 | } 31 | 32 | order3 := entities.Order{ 33 | ID: 3, 34 | UserFullName: "Reza Mac", 35 | UserId: "", 36 | Price: float64(210), 37 | Status: true, 38 | NotificationType: "", 39 | } 40 | 41 | orderService := services.NewOrderService() 42 | err, _ := orderService.CreateOrder(&order1) 43 | if err != nil { 44 | logger.Error().Interface("entityInfo", order1).Err(err).Msg("Order 1 is not valid") 45 | } 46 | err, _ = orderService.CreateOrder(&order2) 47 | 48 | if err != nil { 49 | logger.Error().Interface("entityInfo", order2).Err(err).Msg("Order 1 is not valid") 50 | } 51 | 52 | err, _ = orderService.CreateOrder(&order3) 53 | if err != nil { 54 | logger.Error().Interface("entityInfo", order3).Err(err).Msg("Order 1 is not valid") 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /14-Logging/04-MiniProject/services/orderService.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "notification/core" 7 | "notification/entities" 8 | "notification/externalServices" 9 | ) 10 | 11 | var logger = core.NewFileLogger() 12 | 13 | type OrderService struct { 14 | externalServices.Notifier 15 | } 16 | 17 | func (orderService *OrderService) CreateOrder(order *entities.Order) (error, *entities.Order) { 18 | if !order.Status { 19 | return errors.New("order is not valid"), order 20 | } 21 | 22 | if order.Price < 150 { 23 | return errors.New("order price is not valid"), order 24 | } 25 | 26 | fmt.Printf("Order created: %v\n", order) 27 | 28 | logger.Info().Interface("Order", order).Msg("Order created:") 29 | 30 | orderService.Notifier = externalServices.NewNotifier(order.NotificationType) 31 | 32 | logger.Info().Msgf("Notifier founded: %T", orderService.Notifier) 33 | 34 | err := orderService.SendNotify(order.UserId, "Order created") 35 | 36 | return err, order 37 | } 38 | 39 | func NewOrderService() *OrderService { 40 | return &OrderService{} 41 | } 42 | -------------------------------------------------------------------------------- /15-Concurrency/03-Intro/go.mod: -------------------------------------------------------------------------------- 1 | module intro 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/03-Intro/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | runtime.GOMAXPROCS(runtime.NumCPU()) 10 | value := 0 11 | go task1() 12 | go task2() 13 | go task3() 14 | 15 | go func() { 16 | // lock 17 | value++ //1 18 | //unlock 19 | }() 20 | go func() { 21 | // lock 22 | value+=2 // 3 23 | //unlock 24 | }() 25 | go func() { 26 | // lock 27 | value+=3 // 6 28 | //unlock 29 | }() 30 | 31 | println(value) 32 | 33 | time.Sleep(time.Second) 34 | } 35 | 36 | func task1() { 37 | println("task1") 38 | } 39 | 40 | func task2() { 41 | println("task2") 42 | } 43 | 44 | func task3() { 45 | println("task3") 46 | } 47 | 48 | // race condition 49 | //await -------------------------------------------------------------------------------- /15-Concurrency/04-WaitGroups/go.mod: -------------------------------------------------------------------------------- 1 | module waitGroup 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/04-WaitGroups/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "strconv" 8 | "sync" 9 | ) 10 | 11 | var TodoList = []string{} 12 | 13 | func main() { 14 | wg := sync.WaitGroup{} 15 | wg.Add(50) // 50 - 50 = 0 16 | for i := 0; i < 50; i++ { 17 | //wg.Add(1) 18 | go GetTodo(i+1, &wg) 19 | } 20 | 21 | wg.Wait() 22 | fmt.Printf("%v", TodoList) 23 | 24 | } 25 | 26 | func GetTodo(id int, wg *sync.WaitGroup) { 27 | //"https://jsonplaceholder.typicode.com/todos/1" 28 | GetUrl("https://jsonplaceholder.typicode.com/todos/"+strconv.Itoa(id), wg) 29 | } 30 | 31 | func GetUrl(url string, wg *sync.WaitGroup) { 32 | defer wg.Done() 33 | response, err := http.Get(url) 34 | 35 | if err != nil { 36 | panic(err) 37 | } 38 | 39 | responseBody, err := io.ReadAll(response.Body) 40 | defer response.Body.Close() 41 | 42 | if err != nil { 43 | panic(err) 44 | } 45 | 46 | TodoList = append(TodoList, string(responseBody)) 47 | 48 | } 49 | 50 | // main => 51 | // fork task1 task2 task3 task4 task5 52 | 53 | //join 54 | 55 | // 5 56 | // -1 => 4 57 | // -1 => 3 58 | // ... 59 | // -1 => 0 60 | -------------------------------------------------------------------------------- /15-Concurrency/05-Mutex/01-MutexExample/go.mod: -------------------------------------------------------------------------------- 1 | module mutexExample 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/05-Mutex/01-MutexExample/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | SimpleBad() 5 | SimpleGood() 6 | BadAccountDecrease() 7 | MutexAccountDecrease() 8 | AtomicAccountDecrease() 9 | } 10 | -------------------------------------------------------------------------------- /15-Concurrency/05-Mutex/01-MutexExample/mutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | "sync/atomic" 6 | ) 7 | 8 | type Employee struct { 9 | Id int 10 | Salary int64 11 | } 12 | 13 | func MutexAccountDecrease() { 14 | println("Start of MutexAccountDecrease") 15 | println("Write 25_500_000_000 - 25_000_000_000 = 500_000_000") 16 | mx := sync.Mutex{} 17 | wg := sync.WaitGroup{} 18 | 19 | var money int64 = 25_500_000_000 20 | println(money) 21 | employeeSalaryList := []Employee{} 22 | wg.Add(5000) 23 | for i := 0; i < 5_000; i++ { 24 | employeeSalaryList = append(employeeSalaryList, Employee{Id: i, Salary: GetRandomNumber()}) 25 | } 26 | 27 | for _, employee := range employeeSalaryList { 28 | go func(employee Employee) { 29 | defer wg.Done() 30 | if employee.Salary < money { 31 | mx.Lock() 32 | money -= employee.Salary 33 | mx.Unlock() 34 | } 35 | }(employee) 36 | 37 | } 38 | 39 | wg.Wait() 40 | 41 | println(money) 42 | 43 | } 44 | 45 | func AtomicAccountDecrease() { 46 | println("Start of AtomicAccountDecrease") 47 | println("Write 25_500_000_000 - 25_000_000_000 = 500_000_000") 48 | wg := sync.WaitGroup{} 49 | 50 | var money int64 = 25_500_000_000 51 | println(money) 52 | employeeSalaryList := []Employee{} 53 | wg.Add(5000) 54 | for i := 0; i < 5_000; i++ { 55 | employeeSalaryList = append(employeeSalaryList, Employee{Id: i, Salary: GetRandomNumber()}) 56 | } 57 | 58 | for _, employee := range employeeSalaryList { 59 | go func(employee Employee) { 60 | defer wg.Done() 61 | if employee.Salary < money { 62 | atomic.AddInt64(&money, -employee.Salary) 63 | } 64 | }(employee) 65 | 66 | } 67 | 68 | wg.Wait() 69 | 70 | println(money) 71 | 72 | } 73 | 74 | func BadAccountDecrease() { 75 | println("Start of BadAccountDecrease") 76 | println("Write 25_500_000_000 - 25_000_000_000 = 500_000_000") 77 | wg := sync.WaitGroup{} 78 | 79 | var money int64 = 25_500_000_000 80 | println(money) 81 | employeeSalaryList := []Employee{} 82 | wg.Add(5000) 83 | for i := 0; i < 5_000; i++ { 84 | employeeSalaryList = append(employeeSalaryList, Employee{Id: i, Salary: GetRandomNumber()}) 85 | } 86 | 87 | for _, employee := range employeeSalaryList { 88 | go func(employee Employee) { 89 | defer wg.Done() 90 | if employee.Salary < money { 91 | money -= employee.Salary 92 | } 93 | }(employee) 94 | 95 | } 96 | 97 | wg.Wait() 98 | 99 | println(money) 100 | 101 | } 102 | 103 | func GetRandomNumber() int64 { 104 | return 5_000_000 105 | } 106 | -------------------------------------------------------------------------------- /15-Concurrency/05-Mutex/01-MutexExample/simple.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | func SimpleGood() { 6 | println("Start of SimpleGood") 7 | println("Write 1000000 counter") 8 | mx := sync.Mutex{} 9 | wg := sync.WaitGroup{} 10 | 11 | counter := 0 12 | wg.Add(1000000) 13 | for i := 0; i < 1_000_000; i++ { 14 | go func() { 15 | defer wg.Done() 16 | mx.Lock() 17 | counter++ 18 | mx.Unlock() 19 | }() 20 | } 21 | 22 | wg.Wait() 23 | println(counter) 24 | } 25 | 26 | func SimpleBad() { 27 | println("Start of SimpleBad") 28 | println("Write 1000000 counter") 29 | wg := sync.WaitGroup{} 30 | 31 | counter := 0 32 | wg.Add(1000000) 33 | for i := 0; i < 1_000_000; i++ { 34 | go func() { 35 | defer wg.Done() 36 | counter++ 37 | }() 38 | } 39 | 40 | wg.Wait() 41 | println(counter) 42 | } 43 | -------------------------------------------------------------------------------- /15-Concurrency/05-Mutex/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "sync" 7 | "sync/atomic" 8 | "time" 9 | ) 10 | 11 | var mx = sync.Mutex{} 12 | var rwmx = sync.RWMutex{} 13 | 14 | type Breaker struct { 15 | Name string 16 | Count int64 17 | } 18 | 19 | func main() { 20 | var mci = Breaker{"MCI", 0} 21 | var irancell = Breaker{"Irancell", 0} 22 | var rightel = Breaker{"Rightel", 0} 23 | 24 | for i := 0; i < 10_000; i++ { 25 | go AddBreak(&mci) 26 | go AddBreak(&irancell) 27 | go AddBreak(&rightel) 28 | } 29 | 30 | time.Sleep(time.Second * 2) 31 | 32 | fmt.Printf("MCI: %v\n", mci) 33 | fmt.Printf("Irancell: %v\n", irancell) 34 | fmt.Printf("Rightel: %v\n", rightel) 35 | 36 | } 37 | 38 | func getRandomNumber(min int, max int) int { 39 | return (rand.Intn(max-min) + min) 40 | } 41 | 42 | func AddBreak(breaker *Breaker) { 43 | // rwmx.Lock() 44 | // (*breaker).Count++ 45 | // rwmx.Unlock() 46 | atomic.AddInt64(&((*breaker).Count), 10) 47 | } 48 | 49 | func ReadBreaker(breaker *Breaker) { 50 | rwmx.RLock() 51 | fmt.Printf("%v: %v\n", breaker.Name, breaker.Count) 52 | rwmx.RUnlock() 53 | } 54 | 55 | func ResetBreaker(breaker *Breaker) { 56 | (*breaker).Count = 0 57 | } 58 | -------------------------------------------------------------------------------- /15-Concurrency/06-Cond/example1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | var myList = []int{} 10 | var done = false 11 | 12 | func read(name string, c *sync.Cond) { 13 | defer c.L.Unlock() 14 | c.L.Lock() 15 | if !done { 16 | c.Wait() 17 | } 18 | log.Println(name, "starts reading") 19 | } 20 | 21 | func write(id int, c *sync.Cond) { 22 | log.Println(id, "starts writing") 23 | time.Sleep(time.Second) 24 | c.L.Lock() 25 | myList = append(myList, id) 26 | if len(myList) == 100 { 27 | done = true 28 | c.Broadcast() 29 | log.Println(id, "wakes all") 30 | } 31 | c.L.Unlock() 32 | } 33 | 34 | func RunExample1() { 35 | cond := sync.NewCond(&sync.Mutex{}) 36 | 37 | go read("reader1", cond) 38 | go read("reader2", cond) 39 | go read("reader3", cond) 40 | for i := 0; i < 1000; i++ { 41 | write(i, cond) 42 | } 43 | 44 | time.Sleep(time.Second * 3) 45 | } 46 | 47 | // 48 | -------------------------------------------------------------------------------- /15-Concurrency/06-Cond/go.mod: -------------------------------------------------------------------------------- 1 | module condExample 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/06-Cond/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | var userList = []int{} 9 | var ready = false 10 | 11 | func main() { 12 | 13 | condition := sync.NewCond(&sync.Mutex{}) 14 | 15 | for i := 0; i < 1000; i++ { 16 | go NewRequest(i, condition) 17 | } 18 | 19 | time.Sleep(time.Second * 5) 20 | 21 | } 22 | 23 | func NewRequest(userId int, condition *sync.Cond) { 24 | Checking(userId, condition) 25 | condition.L.Lock() 26 | defer condition.L.Unlock() 27 | for !ready { 28 | condition.Wait() 29 | } 30 | println("User ", userId, "start streaming") // 31 | } 32 | 33 | func Checking(userId int, condition *sync.Cond) { 34 | println(userId, "waiting for start streaming") 35 | time.Sleep(time.Millisecond * 50) 36 | condition.L.Lock() 37 | defer condition.L.Unlock() 38 | userList = append(userList, userId) 39 | if len(userList) == 55 { 40 | ready = true 41 | condition.Broadcast() 42 | println("User ", userId, "waiting end") 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /15-Concurrency/07-Once/bad.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | var ( 6 | mx = sync.Mutex{} 7 | config *Config 8 | ) 9 | 10 | func GetConfigWithSingleton() *Config { 11 | if config == nil { 12 | mx.Lock() 13 | defer mx.Unlock() 14 | if config == nil { 15 | config = &Config{} 16 | println("Creating config") 17 | } 18 | } 19 | println("Get config from old instance") 20 | return config 21 | } 22 | -------------------------------------------------------------------------------- /15-Concurrency/07-Once/go.mod: -------------------------------------------------------------------------------- 1 | module onceExample 2 | 3 | go 1.18 4 | 5 | 6 | //https://medium.com/easyread/just-call-your-code-only-once-256f69ed39a8 -------------------------------------------------------------------------------- /15-Concurrency/07-Once/good.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | var once sync.Once 6 | 7 | func GetConfigWithOnce() *Config { 8 | once.Do(func() { 9 | println("Creating config") 10 | config = &Config{} 11 | }) 12 | println("Get config from old instance") 13 | return config 14 | } 15 | -------------------------------------------------------------------------------- /15-Concurrency/07-Once/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Config struct { 4 | ConnectionString string 5 | } 6 | 7 | func main() { 8 | for i := 0; i < 100; i++ { 9 | config := GetConfigWithOnce() 10 | println(i, ":", &config) 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/01-ConnectionPool/go.mod: -------------------------------------------------------------------------------- 1 | module pool 2 | 3 | go 1.18 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/01-ConnectionPool/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | type DbConnection struct { 9 | Host string 10 | DbName string 11 | User string 12 | Password string 13 | } 14 | 15 | var connectionPool sync.Pool = sync.Pool{ 16 | New: func() interface{} { 17 | return &DbConnection{ 18 | Host: "localhost", 19 | DbName: "test", 20 | User: "root", 21 | Password: "root", 22 | } 23 | }, 24 | } 25 | 26 | func main() { 27 | 28 | connection := connectionPool.Get().(*DbConnection) 29 | 30 | fmt.Printf("%v\n", connection) 31 | 32 | connectionPool.Put(connection) 33 | 34 | connection = connectionPool.Get().(*DbConnection) 35 | 36 | fmt.Printf("%v\n", connection) 37 | 38 | connectionPool.Put(connection) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/01-ConnectionPool/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func BenchmarkWithoutPool(b *testing.B) { 6 | var connection *DbConnection 7 | b.ReportAllocs() 8 | b.ResetTimer() 9 | for i := 0; i < b.N; i++ { 10 | for i := 0; i < 10000; i++ { 11 | connection = &DbConnection{ 12 | Host: "localhost", 13 | DbName: "test", 14 | User: "root", 15 | Password: "root", 16 | } 17 | 18 | connection.DbName = "test" 19 | } 20 | } 21 | 22 | } 23 | 24 | func BenchmarkWithPool(b *testing.B) { 25 | var connection *DbConnection 26 | b.ReportAllocs() 27 | b.ResetTimer() 28 | for i := 0; i < b.N; i++ { 29 | for i := 0; i < 10000; i++ { 30 | connection = connectionPool.Get().(*DbConnection) 31 | connection.DbName = "test" 32 | connectionPool.Put(connection) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/02-Examples/go.mod: -------------------------------------------------------------------------------- 1 | module poolExample 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/02-Examples/main.go: -------------------------------------------------------------------------------- 1 | // https://medium.com/swlh/go-the-idea-behind-sync-pool-32da5089df72 2 | 3 | package main 4 | 5 | func main() { 6 | //RunMemoryUsageExample() 7 | RunNonBufferPoolExample() 8 | //RunBufferPoolExample() 9 | 10 | } 11 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/02-Examples/memoryStatus.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func RunMemoryUsageExample() { 10 | 11 | // Below is an example of using our PrintMemUsage() function 12 | // Print our starting memory usage (should be around 0mb) 13 | PrintMemUsage() 14 | 15 | var overall [][]int 16 | for i := 0; i < 4; i++ { 17 | 18 | // Allocate memory using make() and append to overall (so it doesn't get 19 | // garbage collected). This is to create an ever increasing memory usage 20 | // which we can track. We're just using []int as an example. 21 | a := make([]int, 0, 999999) 22 | overall = append(overall, a) 23 | 24 | // Print our memory usage at each interval 25 | PrintMemUsage() 26 | time.Sleep(time.Second) 27 | } 28 | 29 | // Clear our memory and print usage, unless the GC has run 'Alloc' will remain the same 30 | overall = nil 31 | PrintMemUsage() 32 | 33 | // Force GC to clear up, should see a memory drop 34 | runtime.GC() 35 | PrintMemUsage() 36 | 37 | } 38 | 39 | func PrintMemUsage() { 40 | var m runtime.MemStats 41 | runtime.ReadMemStats(&m) 42 | // For info on each, see: https://golang.org/pkg/runtime/#MemStats 43 | fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc)) 44 | fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc)) 45 | fmt.Printf("\tSys = %v MiB", bToMb(m.Sys)) 46 | fmt.Printf("\tNumGC = %v\n", m.NumGC) 47 | } 48 | 49 | func bToMb(b uint64) uint64 { 50 | return b / 1024 / 1024 51 | } 52 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/02-Examples/poolExample.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "sync" 6 | ) 7 | 8 | var data = make([]byte, 10000) 9 | 10 | var pool = sync.Pool{ 11 | New: func() interface{} { 12 | return &bytes.Buffer{} 13 | }, 14 | } 15 | 16 | func RunBufferPoolExample() { 17 | 18 | PrintMemUsage() 19 | for i := 0; i < 10_000; i++ { 20 | UseBufferWithPool() 21 | } 22 | //runtime.GC() 23 | PrintMemUsage() 24 | 25 | } 26 | 27 | func UseBufferWithPool() { 28 | buf := pool.Get().(*bytes.Buffer) 29 | buf.Write(data) 30 | buf.Reset() 31 | pool.Put(buf) 32 | } 33 | 34 | func UseBuffer() { 35 | var buf bytes.Buffer 36 | buf.Write(data) 37 | } 38 | 39 | func RunNonBufferPoolExample() { 40 | 41 | PrintMemUsage() 42 | for i := 0; i < 10_000; i++ { 43 | UseBuffer() 44 | } 45 | //runtime.GC() 46 | PrintMemUsage() 47 | 48 | } 49 | -------------------------------------------------------------------------------- /15-Concurrency/08-Pool/02-Examples/poolExample_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | ) 7 | 8 | type DbConnection struct { 9 | DbName string 10 | UserId string 11 | Password string 12 | Timeout int 13 | } 14 | 15 | var connectionPool = sync.Pool{ 16 | New: func() any { 17 | return &DbConnection{ 18 | DbName: "DbTest", 19 | UserId: "UserTest", 20 | Password: "PasswordTest", 21 | Timeout: 20, 22 | } 23 | }, 24 | } 25 | 26 | func BenchmarkWithoutPool(b *testing.B) { 27 | var p *DbConnection 28 | b.ReportAllocs() 29 | b.ResetTimer() 30 | for i := 0; i < b.N; i++ { 31 | for j := 0; j < 10000; j++ { 32 | p = &DbConnection{} 33 | p.Timeout = 45 34 | } 35 | } 36 | } 37 | 38 | func BenchmarkWithPool(b *testing.B) { 39 | var p *DbConnection 40 | b.ReportAllocs() 41 | b.ResetTimer() 42 | for i := 0; i < b.N; i++ { 43 | for j := 0; j < 10000; j++ { 44 | p = connectionPool.Get().(*DbConnection) 45 | 46 | connectionPool.Put(p) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /15-Concurrency/09-Channels/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Package", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${fileDirname}" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /15-Concurrency/09-Channels/examples/intro.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func RunIntro() { 9 | numChannel := make(chan int) 10 | 11 | receivedNum := <-numChannel 12 | go SendDataToChannel(numChannel) 13 | 14 | PrintlnWithTime("Received number:", receivedNum) 15 | 16 | receivedNum = <-numChannel 17 | PrintlnWithTime("Received number:", receivedNum) 18 | 19 | time.Sleep(time.Second * 2) 20 | } 21 | 22 | func SendDataToChannel(numChannel chan int) { 23 | PrintlnWithTime("Before sending 1 to channel") 24 | numChannel <- 1 // ChannelName <- data 25 | PrintlnWithTime("After sending 1 to channel") 26 | 27 | PrintlnWithTime("Before sending 2 to channel") 28 | numChannel <- 2 29 | PrintlnWithTime("After sending 2 to channel") 30 | 31 | PrintlnWithTime("Before sending 3 to channel") 32 | numChannel <- 3 33 | PrintlnWithTime("After sending 3 to channel") 34 | 35 | } 36 | 37 | func PrintlnWithTime(args ...any) { 38 | fmt.Printf("Time: %s, %v\n", time.Now().Format(time.RFC3339Nano), args) 39 | } 40 | -------------------------------------------------------------------------------- /15-Concurrency/09-Channels/go.mod: -------------------------------------------------------------------------------- 1 | module concurrency 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/09-Channels/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "concurrency/examples" 4 | 5 | func main() { 6 | examples.RunHttpExample2() 7 | //examples.RunHttpUExample2() 8 | } 9 | package main 10 | 11 | func main() { 12 | 13 | } -------------------------------------------------------------------------------- /15-Concurrency/10-(Un)bufferedChannels/examples/bufferedExamples.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "strconv" 8 | "sync" 9 | "time" 10 | ) 11 | 12 | type RequestResponse struct { 13 | Url string 14 | ResponseBody string 15 | Index int 16 | } 17 | 18 | func BufferedExample() { 19 | total := 100 20 | wg := sync.WaitGroup{} 21 | now := time.Now() 22 | // buffered channel unbuffered channel 23 | // send only, receive only, send and receive 24 | // sender := make(chan<- string) 25 | // receiver := make(<-chan string) 26 | wg.Add(total) 27 | content := make(chan RequestResponse, total) 28 | for i := 0; i < total; i++ { 29 | go GetHttpRequestBuffered(content, &wg) 30 | content <- RequestResponse{Url: "https://jsonplaceholder.typicode.com/todos/" + strconv.Itoa(i+1), Index: i + 1} 31 | } 32 | 33 | wg.Wait() 34 | close(content) 35 | 36 | for item := range content { 37 | PrintlnWithTime(item) 38 | } 39 | 40 | PrintlnWithTime("Time: ", time.Since(now).Milliseconds()) 41 | } 42 | 43 | func GetHttpRequestBuffered(content chan RequestResponse, wg *sync.WaitGroup) { 44 | defer wg.Done() 45 | requestResponse := <-content 46 | response, err := http.Get(requestResponse.Url) 47 | 48 | if err != nil { 49 | panic(err) 50 | } 51 | 52 | defer response.Body.Close() 53 | 54 | responseBody, err := io.ReadAll(response.Body) 55 | 56 | if err != nil { 57 | panic(err) 58 | } 59 | PrintlnWithTime("Before set content") 60 | content <- RequestResponse{Url: requestResponse.Url, ResponseBody: string(responseBody), Index: requestResponse.Index} 61 | 62 | PrintlnWithTime("After set content") 63 | } 64 | 65 | func PrintlnWithTime(args ...any) { 66 | fmt.Printf("Time: %s, %v\n", time.Now().Format(time.RFC3339Nano), args) 67 | } 68 | -------------------------------------------------------------------------------- /15-Concurrency/10-(Un)bufferedChannels/examples/intro.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import "time" 4 | 5 | func IntroExample() { 6 | numChannel := make(chan int) 7 | 8 | go func() { 9 | time.Sleep(time.Second * 3) 10 | numChannel <- 1 11 | }() 12 | 13 | println("Waiting for numChannel", time.Now().String()) 14 | receivedNum := <-numChannel 15 | println("get data ", time.Now().String()) 16 | 17 | println(receivedNum) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /15-Concurrency/10-(Un)bufferedChannels/examples/select.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | func SelectExample() { 13 | 14 | now := time.Now() 15 | resource1 := make(chan string) 16 | resource2 := make(chan string) 17 | go GetHttpRequestSelect(resource1, "https://livescore-api.varzesh3.com/v1.0/livescore/today") 18 | go GetHttpRequestSelect(resource2, "https://footba11.co/json/liveFeed") 19 | 20 | select { 21 | case result1 := <-resource1: 22 | fmt.Println(result1) 23 | break 24 | case result2 := <-resource2: 25 | fmt.Println(result2) 26 | break 27 | case <-time.After(5 * time.Second): 28 | fmt.Println("Timeout") 29 | // default: 30 | // fmt.Println("Default") 31 | } 32 | 33 | println("Time: ", time.Since(now).Milliseconds()) 34 | } 35 | 36 | func GetHttpRequestSelect(content chan<- string, url string) { 37 | if url == "https://livescore-api.varzesh3.com/v1.0/livescore/today" { 38 | time.Sleep(3 * time.Second) 39 | } 40 | client := http.Client{} 41 | req, err := http.NewRequest("GET", url, nil) 42 | if err != nil { 43 | panic(err) 44 | } 45 | 46 | req.Header = http.Header{} 47 | 48 | req.Header.Add("referer", "https://www.varzesh3.com/") 49 | 50 | response, err := client.Do(req) 51 | if err != nil { 52 | panic(err) 53 | } 54 | 55 | defer response.Body.Close() 56 | 57 | responseBody, err := io.ReadAll(response.Body) 58 | 59 | if err != nil { 60 | panic(err) 61 | } 62 | 63 | dst := &bytes.Buffer{} 64 | if err := json.Indent(dst, responseBody, "", " "); err != nil { 65 | panic(err) 66 | } 67 | 68 | PrintlnWithTime("Before set content") 69 | content <- dst.String() 70 | 71 | PrintlnWithTime("After set content") 72 | } 73 | -------------------------------------------------------------------------------- /15-Concurrency/10-(Un)bufferedChannels/examples/unbufferedExamples.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | func UnbufferedExample() { 11 | 12 | now := time.Now() 13 | // buffered channel unbuffered channel 14 | // send only, receive only, send and receive 15 | // sender := make(chan<- string) 16 | // receiver := make(<-chan string) 17 | content := make(chan string) 18 | for i := 0; i < 100; i++ { 19 | go GetHttpRequestUnbuffered(content, i+1) 20 | } 21 | 22 | for i := 0; i < 100; i++ { 23 | response := <-content 24 | println(response) 25 | } 26 | 27 | println("Time: ", time.Since(now).Milliseconds()) 28 | } 29 | 30 | func GetHttpRequestUnbuffered(content chan<- string, index int) { 31 | response, err := http.Get("https://jsonplaceholder.typicode.com/todos/" + strconv.Itoa(index)) 32 | 33 | if err != nil { 34 | panic(err) 35 | } 36 | 37 | defer response.Body.Close() 38 | 39 | responseBody, err := io.ReadAll(response.Body) 40 | 41 | if err != nil { 42 | panic(err) 43 | } 44 | PrintlnWithTime("Before set content") 45 | content <- string(responseBody) 46 | 47 | PrintlnWithTime("After set content") 48 | } 49 | 50 | 51 | type Person struct { 52 | ID int `json:"id"` 53 | FirstName string `json:"first_name"` 54 | LastName string `json:"last_name"` 55 | City string `json:"city"` 56 | } -------------------------------------------------------------------------------- /15-Concurrency/10-(Un)bufferedChannels/go.mod: -------------------------------------------------------------------------------- 1 | module Unbuffered 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/10-(Un)bufferedChannels/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "Unbuffered/examples" 5 | ) 6 | 7 | func main() { 8 | examples.SelectExample() 9 | } 10 | -------------------------------------------------------------------------------- /15-Concurrency/12-Select/go.mod: -------------------------------------------------------------------------------- 1 | module select 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /15-Concurrency/12-Select/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "select/examples" 4 | 5 | func main() { 6 | examples.SelectExample2() 7 | } 8 | -------------------------------------------------------------------------------- /16-Json/examples/marshal.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import "encoding/json" 4 | 5 | type Person struct { 6 | Name string `json:"name"` 7 | Family string `json:"family"` 8 | Age int `json:"age,omitempty"` 9 | } 10 | 11 | func MarshalExample1() { 12 | person1 := Person{Name: "Ali", Family: "Rezaee", Age: 17} 13 | person2 := Person{Name: "Milad", Family: "Mohammadi", Age: 20} 14 | person3 := Person{Name: "Peyman", Family: "Mohammadi", Age: 0} 15 | 16 | person1Json, err := json.Marshal(person1) 17 | if err != nil { 18 | panic(err) 19 | } 20 | person2Json, err := json.Marshal(person2) 21 | if err != nil { 22 | panic(err) 23 | } 24 | person3Json, err := json.Marshal(person3) 25 | if err != nil { 26 | panic(err) 27 | } 28 | 29 | println(string(person1Json)) 30 | println(string(person2Json)) 31 | println(string(person3Json)) 32 | } 33 | 34 | func MarshalExample2() { 35 | person1 := Person{Name: "Ali", Family: "Rezaee", Age: 17} 36 | person2 := Person{Name: "Milad", Family: "Mohammadi", Age: 20} 37 | person3 := Person{Name: "Peyman", Family: "Mohammadi", Age: 0} 38 | 39 | persons := []Person{person1, person2, person3} 40 | personsJson, err := json.Marshal(persons) 41 | if err != nil { 42 | panic(err) 43 | } 44 | 45 | println(string(personsJson)) 46 | } 47 | -------------------------------------------------------------------------------- /16-Json/examples/unMarshal.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | func UnmarshalExample1() { 9 | person1Json := []byte(`{"name":"Ali","family":"Rezaee","age":17}`) 10 | 11 | var person1 = Person{} 12 | err := json.Unmarshal(person1Json, &person1) 13 | 14 | if err != nil { 15 | panic(err) 16 | } 17 | 18 | println(person1.Name) 19 | println(person1.Family) 20 | println(person1.Age) 21 | } 22 | 23 | func UnmarshalExample2() { 24 | personsJson := []byte(`[{"name":"Ali","family":"Rezaee","age":17},{"name":"Milad","family":"Mohammadi","age":20},{"name":"Peyman","family":"Mohammadi"}]`) 25 | 26 | var persons = []Person{} 27 | err := json.Unmarshal(personsJson, &persons) 28 | 29 | if err != nil { 30 | panic(err) 31 | } 32 | 33 | fmt.Printf("%+v", persons) 34 | } 35 | -------------------------------------------------------------------------------- /16-Json/examples/unMarshalFromApi.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "time" 9 | ) 10 | 11 | type BookingLocation struct { 12 | Country string `json:"country"` 13 | State string `json:"state"` 14 | StateName string `json:"stateName"` 15 | ZipCode string `json:"zipcode"` 16 | Timezone string `json:"timezone"` 17 | Latitude string `json:"latitude"` 18 | Longitude string `json:"longitude"` 19 | City string `json:"city"` 20 | Continent string `json:"continent"` 21 | } 22 | 23 | func UnmarshalExample3() { 24 | response := make(chan []byte) 25 | go GetResponse(response, "https://geolocation.onetrust.com/cookieconsentpub/v1/geo/location") 26 | 27 | var location = BookingLocation{} 28 | err := json.Unmarshal(<-response, &location) 29 | 30 | if err != nil { 31 | panic(err) 32 | } 33 | 34 | println(location.City) 35 | println(location.Country) 36 | println(location.StateName) 37 | } 38 | 39 | func GetResponse(content chan<- []byte, url string) { 40 | 41 | client := http.Client{} 42 | 43 | request, err := http.NewRequest("GET", url, nil) 44 | 45 | if err != nil { 46 | panic(err) 47 | } 48 | 49 | request.Header = http.Header{} 50 | 51 | request.Header.Add("accept", "application/json") 52 | 53 | response, err := client.Do(request) 54 | 55 | if err != nil { 56 | panic(err) 57 | } 58 | 59 | defer response.Body.Close() 60 | 61 | responseBody, err := ioutil.ReadAll(response.Body) 62 | 63 | if err != nil { 64 | panic(err) 65 | } 66 | 67 | PrintlnWithTime(string(responseBody)) 68 | PrintlnWithTime("Before set content") 69 | content <- responseBody 70 | PrintlnWithTime("After set content") 71 | 72 | } 73 | 74 | func PrintlnWithTime(args ...any) { 75 | fmt.Printf("Time: %s, %v\n", time.Now().Format(time.RFC3339Nano), args) 76 | } 77 | -------------------------------------------------------------------------------- /16-Json/go.mod: -------------------------------------------------------------------------------- 1 | module jsonExamples 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /16-Json/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "jsonExamples/examples" 4 | 5 | func main() { 6 | // examples.MarshalExample1() 7 | // examples.MarshalExample2() 8 | // examples.UnmarshalExample1() 9 | // examples.UnmarshalExample2() 10 | examples.UnmarshalExample3() 11 | } 12 | -------------------------------------------------------------------------------- /17-Http/02-Server/examples/servemux.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | type TestHandler struct { 10 | } 11 | 12 | func CreateServerWithMux() { 13 | mux := http.NewServeMux() 14 | 15 | mux.Handle("/google", http.RedirectHandler("http://www.google.com", 307)) 16 | mux.Handle("/yahoo", http.RedirectHandler("http://www.yahoo.com", 307)) 17 | mux.HandleFunc("/get-users", GetUsers) 18 | mux.HandleFunc("/get-status", GetStatus) 19 | 20 | server1 := &http.Server{ 21 | Addr: ":8080", 22 | ReadTimeout: time.Second * 10, 23 | WriteTimeout: time.Second * 10, 24 | Handler: mux, 25 | } 26 | 27 | err := server1.ListenAndServe() 28 | 29 | if err != nil { 30 | panic(err) 31 | } 32 | } 33 | 34 | func CreateServerWithCustomHandler() { 35 | 36 | server1 := &http.Server{ 37 | Addr: ":8080", 38 | ReadTimeout: time.Second * 10, 39 | WriteTimeout: time.Second * 10, 40 | Handler: TestHandler{}, 41 | } 42 | 43 | err := server1.ListenAndServe() 44 | 45 | if err != nil { 46 | panic(err) 47 | } 48 | } 49 | 50 | func (h TestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 51 | w.WriteHeader(401) 52 | fmt.Fprintf(w, "Hello, world!") 53 | } 54 | 55 | func GetUsers(w http.ResponseWriter, r *http.Request) { 56 | w.WriteHeader(200) 57 | 58 | fmt.Fprintf(w, "{'id': '%d', 'name': '%s', 'method': '%s'}", 10, "Peyman", r.Method) 59 | } 60 | 61 | func GetStatus(w http.ResponseWriter, r *http.Request) { 62 | fmt.Fprintf(w, "I am OK") 63 | } 64 | -------------------------------------------------------------------------------- /17-Http/02-Server/examples/server.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func CreateServer() { 10 | go func() { 11 | server1 := &http.Server{ 12 | Addr: ":8080", 13 | ReadTimeout: time.Second * 10, 14 | WriteTimeout: time.Second * 10, 15 | } 16 | 17 | err := server1.ListenAndServe() 18 | 19 | if err != nil { 20 | panic(err) 21 | } 22 | }() 23 | 24 | log.Fatal(http.ListenAndServe(":8090", nil)) 25 | } 26 | -------------------------------------------------------------------------------- /17-Http/02-Server/go.mod: -------------------------------------------------------------------------------- 1 | module http-examples 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /17-Http/02-Server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "http-examples/examples" 4 | 5 | // HTTP Server 6 | // Routing and handlers 7 | // HTTP request segments // url, method, path, query, params, headers, body 8 | // HTTP response segments , statusCode, body, headers 9 | // Context 10 | // Mini Project => Simple CRUD store without database 11 | 12 | func main() { 13 | // 02- Create server 14 | //examples.CreateServer() 15 | 16 | // 03- Create server and servemux 17 | examples.CreateServerWithMux() 18 | 19 | } 20 | -------------------------------------------------------------------------------- /17-Http/04-RequestManagement/go.mod: -------------------------------------------------------------------------------- 1 | module http-request-examples 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /17-Http/04-RequestManagement/handler/users.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "http-request-examples/models" 7 | "net/http" 8 | ) 9 | 10 | type UsersHandler struct { 11 | } 12 | 13 | 14 | func (u *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 15 | switch { 16 | 17 | case r.Method == http.MethodGet && len(r.URL.Query().Get("id")) > 0: 18 | GetUser(w, r) 19 | return 20 | case r.Method == http.MethodGet && len(r.URL.Query().Get("id")) == 0: 21 | GetUsers(w, r) 22 | return 23 | case r.Method == http.MethodPost: 24 | CreateUser(w, r) 25 | return 26 | } 27 | } 28 | 29 | func CreateUser(w http.ResponseWriter, r *http.Request) { 30 | apiKey := r.Header.Get("X-Api-Key") 31 | 32 | for k, v := range r.Header { 33 | fmt.Println(k, v) 34 | } 35 | 36 | if apiKey != "9289652658659856" { 37 | w.WriteHeader(401) 38 | fmt.Fprintf(w, "Invalid API Key") 39 | return 40 | } 41 | 42 | var user *models.User 43 | 44 | err := json.NewDecoder(r.Body).Decode(&user) 45 | if err != nil { 46 | w.WriteHeader(500) 47 | fmt.Fprintf(w, "Decode Error: %v", err) 48 | return 49 | } 50 | 51 | w.WriteHeader(200) 52 | fmt.Fprintf(w, "User created") 53 | 54 | } 55 | 56 | func GetUser(w http.ResponseWriter, r *http.Request) { 57 | id := r.URL.Query().Get("id") 58 | // get form db 59 | fmt.Fprintf(w, "get user by id: %s", id) 60 | } 61 | 62 | func GetUsers(w http.ResponseWriter, r *http.Request) { 63 | // get list form db 64 | fmt.Fprintf(w, "get users") 65 | } 66 | -------------------------------------------------------------------------------- /17-Http/04-RequestManagement/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "http-request-examples/management" 4 | 5 | // URL path 6 | // Get Query Parameters 7 | // Read Headers 8 | // Read Request Body 9 | // Decode body to struct 10 | 11 | // Local storage 12 | // Standard Response 13 | // Write to header 14 | // Write Body 15 | 16 | func main() { 17 | management.Run() 18 | } 19 | -------------------------------------------------------------------------------- /17-Http/04-RequestManagement/management/server.go: -------------------------------------------------------------------------------- 1 | package management 2 | 3 | import ( 4 | handlers "http-request-examples/handler" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func Run() { 10 | mux := http.NewServeMux() 11 | mux.Handle("/users/", &handlers.UsersHandler{}) 12 | server := &http.Server{ 13 | Addr: ":8080", 14 | ReadTimeout: time.Second * 10, 15 | WriteTimeout: time.Second * 10, 16 | Handler: mux, 17 | } 18 | 19 | err := server.ListenAndServe() 20 | 21 | if err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /17-Http/04-RequestManagement/models/user.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type User struct { 4 | Id int `json:"id"` 5 | FullName string `json:"fullName"` 6 | Age int `json:"age"` 7 | } 8 | -------------------------------------------------------------------------------- /17-Http/05-ResponseManagement/api/result.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | type ApiResult struct { 9 | Success bool `json:"success"` 10 | Result interface{} `json:"result"` 11 | Error string `json:"error"` 12 | } 13 | 14 | func SetResult(statusCode int, result interface{}, errorInfo error, w http.ResponseWriter) { 15 | w.Header().Add("Web-Server", "NGINX") 16 | w.Header().Set("Content-Type", "application/json") 17 | 18 | apiResult := &ApiResult{} 19 | if statusCode == http.StatusOK { 20 | apiResult.Success = true 21 | } else { 22 | apiResult.Success = false 23 | } 24 | 25 | apiResult.Result = result 26 | 27 | if errorInfo != nil { 28 | apiResult.Error = errorInfo.Error() 29 | } 30 | 31 | jsonResponse, err := json.Marshal(apiResult) 32 | if err != nil { 33 | apiResult.Success = false 34 | apiResult.Error = err.Error() 35 | w.WriteHeader(http.StatusInternalServerError) 36 | } 37 | 38 | w.WriteHeader(statusCode) 39 | _, err = w.Write(jsonResponse) 40 | if err != nil { 41 | panic(err) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /17-Http/05-ResponseManagement/go.mod: -------------------------------------------------------------------------------- 1 | module http-request-examples 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /17-Http/05-ResponseManagement/handler/users.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "http-request-examples/api" 8 | "http-request-examples/models" 9 | "net/http" 10 | "strconv" 11 | ) 12 | 13 | type UsersHandler struct { 14 | } 15 | 16 | var Users = map[string]models.User{} 17 | 18 | func (u *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 19 | switch { 20 | 21 | case r.Method == http.MethodGet && len(r.URL.Query().Get("id")) > 0: 22 | GetUser(w, r) 23 | return 24 | case r.Method == http.MethodGet && len(r.URL.Query().Get("id")) == 0: 25 | GetUsers(w, r) 26 | return 27 | case r.Method == http.MethodPost: 28 | CreateUser(w, r) 29 | return 30 | } 31 | } 32 | 33 | func CreateUser(w http.ResponseWriter, r *http.Request) { 34 | apiKey := r.Header.Get("X-Api-Key") 35 | 36 | for k, v := range r.Header { 37 | fmt.Println(k, v) 38 | } 39 | 40 | if apiKey != "9289652658659856" { 41 | api.SetResult(http.StatusUnauthorized, nil, nil, w) 42 | return 43 | } 44 | 45 | var user *models.User 46 | 47 | err := json.NewDecoder(r.Body).Decode(&user) 48 | if err != nil { 49 | api.SetResult(http.StatusInternalServerError, nil, err, w) 50 | return 51 | } 52 | 53 | // add to db 54 | if _, exists := Users[strconv.Itoa(user.Id)]; exists { 55 | api.SetResult(http.StatusInternalServerError, nil, errors.New("User is exists"), w) 56 | return 57 | } 58 | Users[strconv.Itoa(user.Id)] = *user 59 | 60 | api.SetResult(http.StatusOK, *user, nil, w) 61 | } 62 | 63 | func GetUser(w http.ResponseWriter, r *http.Request) { 64 | id := r.URL.Query().Get("id") 65 | 66 | // get form db 67 | user, exists := Users[id] 68 | 69 | if exists { 70 | api.SetResult(http.StatusOK, user, nil, w) 71 | } else { 72 | api.SetResult(http.StatusNotFound, nil, nil, w) 73 | } 74 | } 75 | 76 | func GetUsers(w http.ResponseWriter, r *http.Request) { 77 | api.SetResult(http.StatusOK, Users, nil, w) 78 | } 79 | -------------------------------------------------------------------------------- /17-Http/05-ResponseManagement/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "http-request-examples/management" 4 | 5 | // URL path 6 | // Get Query Parameters 7 | // Read Headers 8 | // Read Request Body 9 | // Decode body to struct 10 | 11 | // Local storage 12 | // Standard Response 13 | // Write to header 14 | // Write Body 15 | 16 | func main() { 17 | management.Run() 18 | } 19 | -------------------------------------------------------------------------------- /17-Http/05-ResponseManagement/management/server.go: -------------------------------------------------------------------------------- 1 | package management 2 | 3 | import ( 4 | handlers "http-request-examples/handler" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func Run() { 10 | mux := http.NewServeMux() 11 | mux.Handle("/users/", &handlers.UsersHandler{}) 12 | server := &http.Server{ 13 | Addr: ":8080", 14 | ReadTimeout: time.Second * 10, 15 | WriteTimeout: time.Second * 10, 16 | Handler: mux, 17 | } 18 | 19 | err := server.ListenAndServe() 20 | 21 | if err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /17-Http/05-ResponseManagement/models/user.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type User struct { 4 | Id int `json:"id"` 5 | FullName string `json:"fullName"` 6 | Age int `json:"age"` 7 | } 8 | -------------------------------------------------------------------------------- /17-Http/06-Context/api/result.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | type ApiResult struct { 9 | Success bool `json:"success"` 10 | Result interface{} `json:"result"` 11 | Error string `json:"error"` 12 | } 13 | 14 | func SetResult(statusCode int, result interface{}, errorInfo error, w http.ResponseWriter) { 15 | w.Header().Add("Web-Server", "NGINX") 16 | w.Header().Set("Content-Type", "application/json") 17 | 18 | apiResult := &ApiResult{} 19 | if statusCode == http.StatusOK { 20 | apiResult.Success = true 21 | } else { 22 | apiResult.Success = false 23 | } 24 | 25 | apiResult.Result = result 26 | 27 | if errorInfo != nil { 28 | apiResult.Error = errorInfo.Error() 29 | } 30 | 31 | jsonResponse, err := json.Marshal(apiResult) 32 | if err != nil { 33 | apiResult.Success = false 34 | apiResult.Error = err.Error() 35 | w.WriteHeader(http.StatusInternalServerError) 36 | } 37 | 38 | w.WriteHeader(statusCode) 39 | _, err = w.Write(jsonResponse) 40 | if err != nil { 41 | panic(err) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /17-Http/06-Context/examples/internal_cancel.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import ( 4 | "context" 5 | "time" 6 | ) 7 | 8 | func InternalCancellationExample() { 9 | ctx := context.Background() 10 | ctx, cancel := context.WithCancel(ctx) 11 | 12 | //Timeout 13 | //ctx, cancel = context.WithTimeout(ctx, time.Second * 3) 14 | 15 | //Deadline 16 | //ctx, cancel = context.WithDeadline(ctx, time.Date(2022, time.February, 13, 23, 30, 0, 0, time.UTC)) 17 | 18 | defer cancel() 19 | 20 | go func() { 21 | for { 22 | if time.Now().Second()%12 == 0 { 23 | cancel() 24 | } 25 | } 26 | }() 27 | 28 | Processor(ctx, 0) 29 | } 30 | 31 | func Processor(ctx context.Context, num int) { 32 | for { 33 | num++ 34 | select { 35 | case <-ctx.Done(): 36 | println("Canceled...") 37 | return 38 | default: 39 | println("processing", num) 40 | } 41 | time.Sleep(time.Millisecond * 500) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /17-Http/06-Context/examples/send_value.go: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import "context" 4 | 5 | func SendValueExample() { 6 | ctx := context.Background() 7 | 8 | ctx = context.WithValue(ctx, "api-key", "1234567890") 9 | ctx = context.WithValue(ctx, "api-key", "1234567891") 10 | ctx = context.WithValue(ctx, "validation-code", "1020304050") 11 | 12 | Print(ctx) 13 | 14 | } 15 | 16 | func Print(ctx context.Context) { 17 | var apiKey = ctx.Value("api-key") 18 | var validationCode = ctx.Value("validation-code") 19 | 20 | println(apiKey.(string), validationCode.(string)) 21 | } 22 | -------------------------------------------------------------------------------- /17-Http/06-Context/go.mod: -------------------------------------------------------------------------------- 1 | module context-examples 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /17-Http/06-Context/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context-examples/examples" 5 | "context-examples/management" 6 | ) 7 | 8 | /* 9 | Context 10 | Creation 11 | Send value 12 | Cancellation from request 13 | Internal cancellation 14 | timeout 15 | Deadline 16 | 17 | */ 18 | func main() { 19 | // Creation 20 | examples.SendValueExample() 21 | 22 | //External Cancellation 23 | management.Run() 24 | 25 | // Internal Cancellation 26 | examples.InternalCancellationExample() 27 | 28 | } 29 | -------------------------------------------------------------------------------- /17-Http/06-Context/management/server.go: -------------------------------------------------------------------------------- 1 | package management 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func Run() { 10 | mux := http.NewServeMux() 11 | mux.HandleFunc("/test/", TestHandler) 12 | 13 | server := &http.Server{ 14 | Addr: ":8080", 15 | ReadTimeout: time.Second * 10, 16 | WriteTimeout: time.Second * 10, 17 | Handler: mux, 18 | } 19 | 20 | err := server.ListenAndServe() 21 | 22 | if err != nil { 23 | panic(err) 24 | } 25 | } 26 | 27 | func TestHandler(w http.ResponseWriter, r *http.Request) { 28 | ctx := r.Context() 29 | 30 | select { 31 | case <-time.After(time.Second * 5): 32 | fmt.Println("processing request") 33 | fmt.Fprintf(w, "Response") 34 | case <-ctx.Done(): 35 | fmt.Println("cancel request") 36 | return 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Package", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /17-Http/07-MiniProject/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.19-buster as builder 2 | 3 | WORKDIR /app 4 | 5 | COPY go.* ./ 6 | RUN go mod download 7 | 8 | COPY . ./ 9 | 10 | RUN go build -v -o server 11 | 12 | COPY ./ ./app/server 13 | 14 | CMD ["/app/server"] -------------------------------------------------------------------------------- /17-Http/07-MiniProject/database/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import "http-mini-project/models" 4 | 5 | // set up a database dummy 6 | var ( 7 | MovieDb = make(map[string]models.Movie) 8 | ) 9 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/go.mod: -------------------------------------------------------------------------------- 1 | module http-mini-project 2 | 3 | go 1.19 4 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "http-mini-project/management" 4 | 5 | func main() { 6 | management.Run() 7 | } 8 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/management/server.go: -------------------------------------------------------------------------------- 1 | package management 2 | 3 | import ( 4 | "http-mini-project/handlers" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func Run() { 10 | mux := http.NewServeMux() 11 | mux.Handle("/movies/", &handlers.MovieHandler{}) 12 | server := &http.Server{ 13 | Addr: ":8085", 14 | ReadTimeout: time.Second * 10, 15 | WriteTimeout: time.Second * 10, 16 | Handler: mux, 17 | } 18 | 19 | err := server.ListenAndServe() 20 | 21 | if err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/models/movie.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | // Movie for modeling data dummy 4 | type Movie struct { 5 | ID string `json:"id"` 6 | Title string `json:"title"` 7 | Description string `json:"description"` 8 | } 9 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/utils/api_error.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | type ApiError struct { 4 | Id string `json:"id"` 5 | Message string `json:"message"` 6 | } 7 | -------------------------------------------------------------------------------- /17-Http/07-MiniProject/utils/api_result.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | type ApiResult struct { 9 | Success bool `json:"success"` 10 | Result interface{} `json:"result"` 11 | Error interface{} `json:"error"` 12 | } 13 | 14 | func SetResult(w http.ResponseWriter, statusCode int, result interface{}, errorInfo interface{}) { 15 | 16 | w.Header().Add("Web-Server", "NGINX") 17 | w.Header().Set("Content-Type", "application/json") 18 | 19 | apiResult := &ApiResult{} 20 | if statusCode == http.StatusOK { 21 | apiResult.Success = true 22 | } else { 23 | apiResult.Success = false 24 | } 25 | 26 | apiResult.Result = result 27 | 28 | if errorInfo != nil { 29 | apiResult.Error = errorInfo 30 | } 31 | 32 | jsonResponse, err := json.Marshal(apiResult) 33 | if err != nil { 34 | apiResult.Success = false 35 | apiResult.Error = err.Error() 36 | w.WriteHeader(http.StatusInternalServerError) 37 | } 38 | 39 | w.WriteHeader(statusCode) 40 | _, err = w.Write(jsonResponse) 41 | if err != nil { 42 | panic(err) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /20-Docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | postgres: 4 | container_name: pgdb 5 | image: postgres 6 | hostname: postgres 7 | ports: 8 | - "5432:5432" 9 | environment: 10 | POSTGRES_USER: postgres 11 | POSTGRES_PASSWORD: admin 12 | POSTGRES_DB: TEST_SM 13 | volumes: 14 | - postgres-data:/var/lib/postgresql/data 15 | restart: unless-stopped 16 | 17 | pgadmin: 18 | image: dpage/pgadmin4 19 | depends_on: 20 | - postgres 21 | ports: 22 | - "8090:80" 23 | environment: 24 | PGADMIN_DEFAULT_EMAIL: hamed@test.com 25 | PGADMIN_DEFAULT_PASSWORD: admin 26 | restart: unless-stopped 27 | 28 | volumes: 29 | postgres-data: -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Golang Tutorial [Course Address](https://7learn.com/course/golang-expert) 2 | 3 | # Basic 4 | ## [Section 1 : Intro](01) 5 | 6 | ## [Section 2 : Requirements](02-Introduction) 7 | 8 | ## [Section 3 : Data types](03-DataTypes) 9 | 10 | ## [Section 4 : Const and variables](04-Variables) 11 | 12 | ## [Section 5 : Conditional statements](05-ConditionalStatements) 13 | 14 | ## [Section 6 : Loop statements](06-Loops) 15 | 16 | ## [Section 7 : Composite data types](07-CompositeDataTypes) 17 | 18 | ## [Section 8 : Functions](08-Function) 19 | 20 | ## [Section 9 : Structs](09-Structs) 21 | 22 | ## [Section 10 : Interface](10-Interfaces) 23 | 24 | ## [Section 11 : Modules](11-Modules) 25 | 26 | # Advanced 27 | 28 | ## [Section 12 : Generics](12-Generics) 29 | 30 | ## [Section 13 : Errors](13-Errors) 31 | 32 | ## [Section 14 : Logging](14-Logging) 33 | 34 | ## [Section 15 : Concurrency](15-Concurrency) 35 | 36 | ## [Section 16 : Json](16-Json) 37 | 38 | ## [Section 17 : Http](17-Http) 39 | 40 | ## [Section 18 : Test](18-Test) 41 | --------------------------------------------------------------------------------